diff options
author | Adam <Adam@anope.org> | 2010-06-19 11:54:08 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-06-19 11:54:08 -0400 |
commit | 52058fe87b4b0475b1775198c725af14e540d355 (patch) | |
tree | c3597d6411a006ffbb670d2ce761101b9640e9b6 | |
parent | 43e951aed54f838ba55a4c1552214773aee2fb2f (diff) | |
parent | df9d291bcba9788e51d11424ebaf6f05c26cc80f (diff) |
Merge remote branch 'origin/1.9.3' into 1.9
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | data/example.conf | 139 | ||||
-rw-r--r-- | data/tables.sql | 8 | ||||
-rw-r--r-- | docs/Changes | 8 | ||||
-rw-r--r-- | docs/Changes.conf | 18 | ||||
-rw-r--r-- | docs/Changes.lang | 101 | ||||
-rw-r--r-- | docs/IRCD | 4 | ||||
-rw-r--r-- | docs/WIN32.txt | 16 | ||||
-rw-r--r-- | empty.c | 0 | ||||
-rw-r--r-- | include/CMakeLists.txt | 4 | ||||
-rw-r--r-- | include/Makefile | 10 | ||||
-rw-r--r-- | include/account.h | 21 | ||||
-rw-r--r-- | include/bots.h | 27 | ||||
-rw-r--r-- | include/channels.h | 8 | ||||
-rw-r--r-- | include/commands.h | 109 | ||||
-rw-r--r-- | include/config.h | 920 | ||||
-rw-r--r-- | include/configreader.h | 903 | ||||
-rw-r--r-- | include/defs.h | 39 | ||||
-rw-r--r-- | include/extern.h | 191 | ||||
-rw-r--r-- | include/hashcomp.h | 59 | ||||
-rw-r--r-- | include/mail.h | 24 | ||||
-rw-r--r-- | include/messages.h | 22 | ||||
-rw-r--r-- | include/modes.h | 87 | ||||
-rw-r--r-- | include/modules.h | 422 | ||||
-rw-r--r-- | include/operserv.h | 231 | ||||
-rw-r--r-- | include/opertype.h | 9 | ||||
-rw-r--r-- | include/pseudo.h | 17 | ||||
-rw-r--r-- | include/regchannel.h | 33 | ||||
-rw-r--r-- | include/servers.h | 179 | ||||
-rw-r--r-- | include/services.h | 264 | ||||
-rw-r--r-- | include/slist.h | 49 | ||||
-rw-r--r-- | include/sockets.h | 2 | ||||
-rw-r--r-- | include/threadengine.h | 117 | ||||
-rw-r--r-- | include/users.h | 25 | ||||
-rw-r--r-- | include/version.sh | 10 | ||||
-rw-r--r-- | include/version.sh.c | 2 | ||||
-rw-r--r-- | install.js | 14 | ||||
-rw-r--r-- | lang/cat.l | 369 | ||||
-rw-r--r-- | lang/de.l | 376 | ||||
-rw-r--r-- | lang/en_us.l | 375 | ||||
-rw-r--r-- | lang/es.l | 385 | ||||
-rw-r--r-- | lang/fr.l | 380 | ||||
-rw-r--r-- | lang/gr.l | 374 | ||||
-rw-r--r-- | lang/hun.l | 367 | ||||
-rw-r--r-- | lang/it.l | 376 | ||||
-rw-r--r-- | lang/nl.l | 375 | ||||
-rw-r--r-- | lang/pl.l | 383 | ||||
-rw-r--r-- | lang/pt.l | 373 | ||||
-rw-r--r-- | lang/ru.l | 377 | ||||
-rw-r--r-- | lang/tr.l | 365 | ||||
-rw-r--r-- | src/CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/Makefile | 96 | ||||
-rw-r--r-- | src/actions.cpp (renamed from src/actions.c) | 46 | ||||
-rw-r--r-- | src/base64.cpp (renamed from src/base64.c) | 0 | ||||
-rw-r--r-- | src/bots.cpp | 93 | ||||
-rw-r--r-- | src/botserv.cpp (renamed from src/botserv.c) | 430 | ||||
-rw-r--r-- | src/channels.cpp (renamed from src/channels.c) | 185 | ||||
-rw-r--r-- | src/chanserv.cpp (renamed from src/chanserv.c) | 483 | ||||
-rw-r--r-- | src/command.cpp | 33 | ||||
-rw-r--r-- | src/commands.cpp (renamed from src/commands.c) | 137 | ||||
-rw-r--r-- | src/compat.cpp (renamed from src/compat.c) | 0 | ||||
-rw-r--r-- | src/config.cpp (renamed from src/config.c) | 50 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/core/Makefile | 8 | ||||
-rw-r--r-- | src/core/bs_act.cpp (renamed from src/core/bs_act.c) | 15 | ||||
-rw-r--r-- | src/core/bs_assign.cpp (renamed from src/core/bs_assign.c) | 13 | ||||
-rw-r--r-- | src/core/bs_badwords.cpp (renamed from src/core/bs_badwords.c) | 185 | ||||
-rw-r--r-- | src/core/bs_bot.cpp (renamed from src/core/bs_bot.c) | 28 | ||||
-rw-r--r-- | src/core/bs_botlist.cpp (renamed from src/core/bs_botlist.c) | 55 | ||||
-rw-r--r-- | src/core/bs_help.cpp (renamed from src/core/bs_help.c) | 7 | ||||
-rw-r--r-- | src/core/bs_info.cpp (renamed from src/core/bs_info.c) | 40 | ||||
-rw-r--r-- | src/core/bs_kick.cpp (renamed from src/core/bs_kick.c) | 13 | ||||
-rw-r--r-- | src/core/bs_say.cpp (renamed from src/core/bs_say.c) | 13 | ||||
-rw-r--r-- | src/core/bs_set.cpp (renamed from src/core/bs_set.c) | 13 | ||||
-rw-r--r-- | src/core/bs_unassign.cpp (renamed from src/core/bs_unassign.c) | 13 | ||||
-rw-r--r-- | src/core/cs_access.c | 589 | ||||
-rw-r--r-- | src/core/cs_access.cpp | 664 | ||||
-rw-r--r-- | src/core/cs_akick.cpp (renamed from src/core/cs_akick.c) | 343 | ||||
-rw-r--r-- | src/core/cs_ban.cpp (renamed from src/core/cs_ban.c) | 21 | ||||
-rw-r--r-- | src/core/cs_clear.cpp (renamed from src/core/cs_clear.c) | 13 | ||||
-rw-r--r-- | src/core/cs_drop.cpp (renamed from src/core/cs_drop.c) | 22 | ||||
-rw-r--r-- | src/core/cs_forbid.cpp (renamed from src/core/cs_forbid.c) | 22 | ||||
-rw-r--r-- | src/core/cs_getkey.cpp (renamed from src/core/cs_getkey.c) | 13 | ||||
-rw-r--r-- | src/core/cs_help.cpp (renamed from src/core/cs_help.c) | 7 | ||||
-rw-r--r-- | src/core/cs_info.cpp (renamed from src/core/cs_info.c) | 23 | ||||
-rw-r--r-- | src/core/cs_invite.cpp (renamed from src/core/cs_invite.c) | 15 | ||||
-rw-r--r-- | src/core/cs_kick.cpp (renamed from src/core/cs_kick.c) | 21 | ||||
-rw-r--r-- | src/core/cs_list.cpp (renamed from src/core/cs_list.c) | 99 | ||||
-rw-r--r-- | src/core/cs_modes.cpp (renamed from src/core/cs_modes.c) | 121 | ||||
-rw-r--r-- | src/core/cs_register.cpp (renamed from src/core/cs_register.c) | 15 | ||||
-rw-r--r-- | src/core/cs_saset.cpp | 131 | ||||
-rw-r--r-- | src/core/cs_saset_noexpire.cpp | 85 | ||||
-rw-r--r-- | src/core/cs_set.c | 839 | ||||
-rw-r--r-- | src/core/cs_set.cpp | 136 | ||||
-rw-r--r-- | src/core/cs_set_bantype.cpp | 113 | ||||
-rw-r--r-- | src/core/cs_set_description.cpp | 107 | ||||
-rw-r--r-- | src/core/cs_set_email.cpp | 106 | ||||
-rw-r--r-- | src/core/cs_set_entrymsg.cpp | 114 | ||||
-rw-r--r-- | src/core/cs_set_founder.cpp | 142 | ||||
-rw-r--r-- | src/core/cs_set_keeptopic.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_mlock.cpp | 197 | ||||
-rw-r--r-- | src/core/cs_set_opnotice.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_peace.cpp | 114 | ||||
-rw-r--r-- | src/core/cs_set_persist.cpp | 163 | ||||
-rw-r--r-- | src/core/cs_set_private.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_restricted.cpp | 116 | ||||
-rw-r--r-- | src/core/cs_set_secure.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_securefounder.cpp | 118 | ||||
-rw-r--r-- | src/core/cs_set_secureops.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_signkick.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_successor.cpp | 145 | ||||
-rw-r--r-- | src/core/cs_set_topiclock.cpp | 112 | ||||
-rw-r--r-- | src/core/cs_set_url.cpp | 114 | ||||
-rw-r--r-- | src/core/cs_set_xop.cpp | 144 | ||||
-rw-r--r-- | src/core/cs_status.cpp (renamed from src/core/cs_status.c) | 13 | ||||
-rw-r--r-- | src/core/cs_suspend.cpp (renamed from src/core/cs_suspend.c) | 27 | ||||
-rw-r--r-- | src/core/cs_topic.cpp (renamed from src/core/cs_topic.c) | 21 | ||||
-rw-r--r-- | src/core/cs_unban.cpp (renamed from src/core/cs_unban.c) | 16 | ||||
-rw-r--r-- | src/core/cs_xop.cpp (renamed from src/core/cs_xop.c) | 299 | ||||
-rw-r--r-- | src/core/db_plain.cpp | 660 | ||||
-rw-r--r-- | src/core/enc_md5.cpp (renamed from src/core/enc_md5.c) | 0 | ||||
-rw-r--r-- | src/core/enc_none.cpp (renamed from src/core/enc_none.c) | 0 | ||||
-rw-r--r-- | src/core/enc_old.cpp (renamed from src/core/enc_old.c) | 0 | ||||
-rw-r--r-- | src/core/enc_sha1.cpp (renamed from src/core/enc_sha1.c) | 0 | ||||
-rw-r--r-- | src/core/enc_sha256.cpp (renamed from src/core/enc_sha256.c) | 0 | ||||
-rw-r--r-- | src/core/hs_del.cpp (renamed from src/core/hs_del.c) | 13 | ||||
-rw-r--r-- | src/core/hs_delall.cpp (renamed from src/core/hs_delall.c) | 21 | ||||
-rw-r--r-- | src/core/hs_group.cpp (renamed from src/core/hs_group.c) | 13 | ||||
-rw-r--r-- | src/core/hs_help.cpp (renamed from src/core/hs_help.c) | 7 | ||||
-rw-r--r-- | src/core/hs_list.cpp (renamed from src/core/hs_list.c) | 80 | ||||
-rw-r--r-- | src/core/hs_off.cpp (renamed from src/core/hs_off.c) | 13 | ||||
-rw-r--r-- | src/core/hs_on.cpp (renamed from src/core/hs_on.c) | 13 | ||||
-rw-r--r-- | src/core/hs_set.cpp (renamed from src/core/hs_set.c) | 13 | ||||
-rw-r--r-- | src/core/hs_setall.cpp (renamed from src/core/hs_setall.c) | 13 | ||||
-rw-r--r-- | src/core/ms_cancel.cpp (renamed from src/core/ms_cancel.c) | 13 | ||||
-rw-r--r-- | src/core/ms_check.cpp (renamed from src/core/ms_check.c) | 13 | ||||
-rw-r--r-- | src/core/ms_del.cpp (renamed from src/core/ms_del.c) | 125 | ||||
-rw-r--r-- | src/core/ms_help.cpp (renamed from src/core/ms_help.c) | 7 | ||||
-rw-r--r-- | src/core/ms_info.cpp (renamed from src/core/ms_info.c) | 13 | ||||
-rw-r--r-- | src/core/ms_list.cpp (renamed from src/core/ms_list.c) | 134 | ||||
-rw-r--r-- | src/core/ms_read.cpp (renamed from src/core/ms_read.c) | 126 | ||||
-rw-r--r-- | src/core/ms_rsend.cpp (renamed from src/core/ms_rsend.c) | 13 | ||||
-rw-r--r-- | src/core/ms_send.cpp (renamed from src/core/ms_send.c) | 13 | ||||
-rw-r--r-- | src/core/ms_sendall.cpp (renamed from src/core/ms_sendall.c) | 31 | ||||
-rw-r--r-- | src/core/ms_set.cpp (renamed from src/core/ms_set.c) | 17 | ||||
-rw-r--r-- | src/core/ms_staff.cpp (renamed from src/core/ms_staff.c) | 28 | ||||
-rw-r--r-- | src/core/ns_access.cpp (renamed from src/core/ns_access.c) | 15 | ||||
-rw-r--r-- | src/core/ns_alist.cpp (renamed from src/core/ns_alist.c) | 47 | ||||
-rw-r--r-- | src/core/ns_drop.cpp (renamed from src/core/ns_drop.c) | 22 | ||||
-rw-r--r-- | src/core/ns_forbid.cpp (renamed from src/core/ns_forbid.c) | 20 | ||||
-rw-r--r-- | src/core/ns_getemail.cpp (renamed from src/core/ns_getemail.c) | 34 | ||||
-rw-r--r-- | src/core/ns_getpass.cpp (renamed from src/core/ns_getpass.c) | 17 | ||||
-rw-r--r-- | src/core/ns_ghost.cpp (renamed from src/core/ns_ghost.c) | 13 | ||||
-rw-r--r-- | src/core/ns_group.cpp (renamed from src/core/ns_group.c) | 122 | ||||
-rw-r--r-- | src/core/ns_help.cpp (renamed from src/core/ns_help.c) | 7 | ||||
-rw-r--r-- | src/core/ns_identify.cpp (renamed from src/core/ns_identify.c) | 22 | ||||
-rw-r--r-- | src/core/ns_info.cpp (renamed from src/core/ns_info.c) | 44 | ||||
-rw-r--r-- | src/core/ns_list.cpp (renamed from src/core/ns_list.c) | 106 | ||||
-rw-r--r-- | src/core/ns_logout.cpp (renamed from src/core/ns_logout.c) | 13 | ||||
-rw-r--r-- | src/core/ns_recover.cpp (renamed from src/core/ns_recover.c) | 13 | ||||
-rw-r--r-- | src/core/ns_register.cpp (renamed from src/core/ns_register.c) | 84 | ||||
-rw-r--r-- | src/core/ns_release.cpp (renamed from src/core/ns_release.c) | 13 | ||||
-rw-r--r-- | src/core/ns_resetpass.cpp (renamed from src/core/ns_resetpass.c) | 97 | ||||
-rw-r--r-- | src/core/ns_saset.c | 599 | ||||
-rw-r--r-- | src/core/ns_saset.cpp | 255 | ||||
-rw-r--r-- | src/core/ns_saset_noexpire.cpp | 87 | ||||
-rw-r--r-- | src/core/ns_sendpass.cpp (renamed from src/core/ns_sendpass.c) | 55 | ||||
-rw-r--r-- | src/core/ns_set.c | 557 | ||||
-rw-r--r-- | src/core/ns_set.cpp | 239 | ||||
-rw-r--r-- | src/core/ns_set_autoop.cpp | 131 | ||||
-rw-r--r-- | src/core/ns_set_email.cpp | 160 | ||||
-rw-r--r-- | src/core/ns_set_greet.cpp | 129 | ||||
-rw-r--r-- | src/core/ns_set_hide.cpp | 200 | ||||
-rw-r--r-- | src/core/ns_set_icq.cpp | 136 | ||||
-rw-r--r-- | src/core/ns_set_kill.cpp | 183 | ||||
-rw-r--r-- | src/core/ns_set_language.cpp | 143 | ||||
-rw-r--r-- | src/core/ns_set_message.cpp | 149 | ||||
-rw-r--r-- | src/core/ns_set_private.cpp | 137 | ||||
-rw-r--r-- | src/core/ns_set_secure.cpp | 137 | ||||
-rw-r--r-- | src/core/ns_set_url.cpp | 128 | ||||
-rw-r--r-- | src/core/ns_status.cpp (renamed from src/core/ns_status.c) | 13 | ||||
-rw-r--r-- | src/core/ns_suspend.cpp (renamed from src/core/ns_suspend.c) | 33 | ||||
-rw-r--r-- | src/core/ns_update.cpp (renamed from src/core/ns_update.c) | 12 | ||||
-rw-r--r-- | src/core/os_akill.c | 409 | ||||
-rw-r--r-- | src/core/os_akill.cpp | 402 | ||||
-rw-r--r-- | src/core/os_chankill.cpp (renamed from src/core/os_chankill.c) | 25 | ||||
-rw-r--r-- | src/core/os_chanlist.cpp (renamed from src/core/os_chanlist.c) | 42 | ||||
-rw-r--r-- | src/core/os_clearmodes.cpp (renamed from src/core/os_clearmodes.c) | 15 | ||||
-rw-r--r-- | src/core/os_defcon.cpp (renamed from src/core/os_defcon.c) | 68 | ||||
-rw-r--r-- | src/core/os_global.cpp (renamed from src/core/os_global.c) | 15 | ||||
-rw-r--r-- | src/core/os_help.cpp (renamed from src/core/os_help.c) | 7 | ||||
-rw-r--r-- | src/core/os_ignore.cpp (renamed from src/core/os_ignore.c) | 18 | ||||
-rw-r--r-- | src/core/os_jupe.cpp (renamed from src/core/os_jupe.c) | 27 | ||||
-rw-r--r-- | src/core/os_kick.cpp (renamed from src/core/os_kick.c) | 17 | ||||
-rw-r--r-- | src/core/os_mode.cpp (renamed from src/core/os_mode.c) | 17 | ||||
-rw-r--r-- | src/core/os_modinfo.cpp (renamed from src/core/os_modinfo.c) | 60 | ||||
-rw-r--r-- | src/core/os_modlist.cpp (renamed from src/core/os_modlist.c) | 120 | ||||
-rw-r--r-- | src/core/os_modload.cpp (renamed from src/core/os_modload.c) | 23 | ||||
-rw-r--r-- | src/core/os_modunload.cpp (renamed from src/core/os_modunload.c) | 23 | ||||
-rw-r--r-- | src/core/os_news.cpp (renamed from src/core/os_news.c) | 36 | ||||
-rw-r--r-- | src/core/os_noop.cpp (renamed from src/core/os_noop.c) | 25 | ||||
-rw-r--r-- | src/core/os_oline.cpp (renamed from src/core/os_oline.c) | 19 | ||||
-rw-r--r-- | src/core/os_quit.cpp (renamed from src/core/os_quit.c) | 13 | ||||
-rw-r--r-- | src/core/os_reload.cpp (renamed from src/core/os_reload.c) | 13 | ||||
-rw-r--r-- | src/core/os_restart.cpp (renamed from src/core/os_restart.c) | 13 | ||||
-rw-r--r-- | src/core/os_session.cpp (renamed from src/core/os_session.c) | 303 | ||||
-rw-r--r-- | src/core/os_set.cpp (renamed from src/core/os_set.c) | 21 | ||||
-rw-r--r-- | src/core/os_sgline.c | 410 | ||||
-rw-r--r-- | src/core/os_shutdown.cpp (renamed from src/core/os_shutdown.c) | 13 | ||||
-rw-r--r-- | src/core/os_snline.cpp | 425 | ||||
-rw-r--r-- | src/core/os_sqline.c | 395 | ||||
-rw-r--r-- | src/core/os_sqline.cpp | 406 | ||||
-rw-r--r-- | src/core/os_staff.cpp (renamed from src/core/os_staff.c) | 17 | ||||
-rw-r--r-- | src/core/os_stats.cpp (renamed from src/core/os_stats.c) | 148 | ||||
-rw-r--r-- | src/core/os_svsnick.cpp (renamed from src/core/os_svsnick.c) | 19 | ||||
-rw-r--r-- | src/core/os_szline.c | 394 | ||||
-rw-r--r-- | src/core/os_szline.cpp | 404 | ||||
-rw-r--r-- | src/core/os_umode.cpp (renamed from src/core/os_umode.c) | 17 | ||||
-rw-r--r-- | src/core/os_update.cpp (renamed from src/core/os_update.c) | 13 | ||||
-rw-r--r-- | src/core/os_userlist.cpp (renamed from src/core/os_userlist.c) | 43 | ||||
-rw-r--r-- | src/core/ss_main.cpp (renamed from src/core/ss_main.c) | 19 | ||||
-rw-r--r-- | src/encrypt.cpp (renamed from src/encrypt.c) | 0 | ||||
-rw-r--r-- | src/hashcomp.cpp | 43 | ||||
-rw-r--r-- | src/hostserv.cpp (renamed from src/hostserv.c) | 71 | ||||
-rw-r--r-- | src/init.cpp (renamed from src/init.c) | 98 | ||||
-rw-r--r-- | src/ircd.cpp (renamed from src/ircd.c) | 0 | ||||
-rw-r--r-- | src/language.cpp (renamed from src/language.c) | 0 | ||||
-rw-r--r-- | src/log.cpp (renamed from src/log.c) | 3 | ||||
-rw-r--r-- | src/mail.c | 283 | ||||
-rw-r--r-- | src/mail.cpp | 151 | ||||
-rw-r--r-- | src/main.cpp (renamed from src/main.c) | 63 | ||||
-rw-r--r-- | src/memory.cpp (renamed from src/memory.c) | 0 | ||||
-rw-r--r-- | src/memoserv.cpp (renamed from src/memoserv.c) | 65 | ||||
-rw-r--r-- | src/messages.cpp (renamed from src/messages.c) | 114 | ||||
-rw-r--r-- | src/misc.cpp (renamed from src/misc.c) | 179 | ||||
-rw-r--r-- | src/modes.cpp | 45 | ||||
-rw-r--r-- | src/module.cpp | 151 | ||||
-rw-r--r-- | src/modulemanager.cpp | 43 | ||||
-rw-r--r-- | src/modules.c | 784 | ||||
-rw-r--r-- | src/modules.cpp | 413 | ||||
-rw-r--r-- | src/modules/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/modules/Makefile | 12 | ||||
-rw-r--r-- | src/modules/cs_appendtopic.cpp (renamed from src/modules/cs_appendtopic.c) | 13 | ||||
-rw-r--r-- | src/modules/cs_enforce.cpp (renamed from src/modules/cs_enforce.c) | 13 | ||||
-rw-r--r-- | src/modules/cs_tban.cpp (renamed from src/modules/cs_tban.c) | 17 | ||||
-rw-r--r-- | src/modules/hs_request.cpp (renamed from src/modules/hs_request.c) | 32 | ||||
-rw-r--r-- | src/modules/mysql/db_mysql.h | 53 | ||||
-rw-r--r-- | src/modules/mysql/db_mysql_execute.cpp | 45 | ||||
-rw-r--r-- | src/modules/mysql/db_mysql_read.cpp | 118 | ||||
-rw-r--r-- | src/modules/mysql/db_mysql_write.cpp | 385 | ||||
-rw-r--r-- | src/modules/ns_maxemail.cpp (renamed from src/modules/ns_maxemail.c) | 13 | ||||
-rw-r--r-- | src/modules/os_info.cpp (renamed from src/modules/os_info.c) | 94 | ||||
-rw-r--r-- | src/modules/ssl/m_ssl.cpp | 148 | ||||
-rw-r--r-- | src/nickalias.cpp | 34 | ||||
-rw-r--r-- | src/nickcore.cpp | 16 | ||||
-rw-r--r-- | src/nickserv.cpp (renamed from src/nickserv.c) | 374 | ||||
-rw-r--r-- | src/operserv.c | 1065 | ||||
-rw-r--r-- | src/operserv.cpp | 828 | ||||
-rw-r--r-- | src/opertype.cpp | 27 | ||||
-rw-r--r-- | src/process.cpp (renamed from src/process.c) | 29 | ||||
-rw-r--r-- | src/protocol.cpp | 4 | ||||
-rw-r--r-- | src/protocol/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/protocol/Makefile | 8 | ||||
-rw-r--r-- | src/protocol/bahamut.cpp (renamed from src/protocol/bahamut.c) | 183 | ||||
-rw-r--r-- | src/protocol/inspircd11.cpp (renamed from src/protocol/inspircd11.c) | 204 | ||||
-rw-r--r-- | src/protocol/inspircd12.cpp | 313 | ||||
-rw-r--r-- | src/protocol/inspircd20.cpp | 314 | ||||
-rw-r--r-- | src/protocol/ratbox.cpp (renamed from src/protocol/ratbox.c) | 166 | ||||
-rw-r--r-- | src/protocol/unreal32.cpp (renamed from src/protocol/unreal32.c) | 330 | ||||
-rw-r--r-- | src/regchannel.cpp | 249 | ||||
-rw-r--r-- | src/send.cpp (renamed from src/send.c) | 18 | ||||
-rw-r--r-- | src/servers.c | 702 | ||||
-rw-r--r-- | src/servers.cpp | 585 | ||||
-rw-r--r-- | src/sessions.cpp (renamed from src/sessions.c) | 87 | ||||
-rw-r--r-- | src/slist.c | 395 | ||||
-rw-r--r-- | src/threadengine.cpp | 37 | ||||
-rw-r--r-- | src/threadengine_pthread.cpp | 113 | ||||
-rw-r--r-- | src/threadengine_win32.cpp | 109 | ||||
-rw-r--r-- | src/tools/db-convert.c | 4 | ||||
-rw-r--r-- | src/users.cpp (renamed from src/users.c) | 300 |
282 files changed, 20121 insertions, 16826 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8493c5835..aabbc4fc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,9 +105,13 @@ if(CMAKE_COMPILER_IS_GNUCXX) if(DEFAULT_LIBRARY_DIRS) remove_list_duplicates(DEFAULT_LIBRARY_DIRS) endif(DEFAULT_LIBRARY_DIRS) + # Create a temporary file to test for the default include directories + FILE(WRITE empty.cpp "") # Next, we look for the compiler's default include directories # Run the command to find the default include directories - execute_process(COMMAND ${CMAKE_C_COMPILER} -v -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/empty.c ERROR_VARIABLE LINES OUTPUT_QUIET ERROR_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${CMAKE_C_COMPILER} -v -x c++ -E ${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp ERROR_VARIABLE LINES OUTPUT_QUIET ERROR_STRIP_TRAILING_WHITESPACE) + # Remove the empty file, it is no longer needed + FILE(REMOVE empty.cpp) # Convert the new lines to semicolons string(REGEX REPLACE "\n" ";" LINES ${LINES}) # Temporary variable saying if we are in the search list or not @@ -286,6 +290,13 @@ if(NOT MSVC) if(HAVE_NSL_LIB) set(LDFLAGS "${LDFLAGS} -lnsl") endif(HAVE_NSL_LIB) + # Check if pthread_create is within the pthread library (if the library exists), and add it to the linker flags if needed + check_library_exists(pthread pthread_create "" HAVE_PTHREAD) + if(HAVE_PTHREAD) + set(LDFLAGS "${LDFLAGS} -pthread") + else(HAVE_PTHREAD) + message(FATAL_ERROR "The pthread library is required to build Anope") + endif(HAVE_PTHREAD) endif(NOT WIN32) endif(NOT MSVC) @@ -598,7 +598,7 @@ PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= -ac_unique_file="src/actions.c" +ac_unique_file="src/actions.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> @@ -3398,6 +3398,8 @@ fi +ANOPELIBS="$ANOPELIBS -pthread" + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' diff --git a/configure.in b/configure.in index 4fb762d66..13ba368fe 100644 --- a/configure.in +++ b/configure.in @@ -21,7 +21,7 @@ if test "${with_instdir+set}" != set; then exit 0 fi -AC_CONFIG_SRCDIR([src/actions.c]) +AC_CONFIG_SRCDIR([src/actions.cpp]) AC_CONFIG_HEADER(include/sysconf.h) AC_PROG_CC if test "$ac_cv_c_compiler_gnu" = "yes"; then @@ -95,6 +95,8 @@ int main() AC_SUBST(ANOPELIBS) AC_SUBST(LDFLAGS) +ANOPELIBS="$ANOPELIBS -pthread" + AC_CHECK_HEADER(sys/types.h,AC_DEFINE(HAS_SYS_TYPES_H,1,"Has sys/types.h")) dnl module checking based on Unreal's module checking code AC_DEFUN(AC_ENABLE_DYN, diff --git a/data/example.conf b/data/example.conf index b9ee1fd1b..90864f96a 100644 --- a/data/example.conf +++ b/data/example.conf @@ -91,10 +91,16 @@ uplink host = "localhost" /* - * Enable if Services should connect using IPv6 + * Enable if Services should connect using IPv6. */ ipv6 = no + /* + * Enable if Services should connect using SSL. + * You must have m_ssl loaded for this to work. + */ + ssl = no + /* * The port to connect to. * The IRCd *MUST* be configured to listen on this port, and to accept @@ -576,6 +582,7 @@ options * chanserv/set - Can modify the settings of any channel (incl. changing of the owner and password!) * memoserv/info - Can see any information with /memoserv info * memoserv/set-limit - Can set the limit of max stored memos on any user and channel + * nickserv/auspex - Can see any information with /nickserv info * nickserv/confirm - Can confirm other users nicknames * nickserv/drop - Can drop other users nicks * @@ -583,20 +590,30 @@ options * botserv/bot/del botserv/bot/add botserv/bot/change botserv/assign/private * botserv/botlist botserv/set/private botserv/set/nobot * - * chanserv/access/list chanserv/drop chanserv/forbid chanserv/getkey - * chanserv/list chanserv/suspend chanserv/topic chanserv/set/noexpire - * chanserv/status + * chanserv/access/list chanserv/drop chanserv/forbid chanserv/getkey + * chanserv/list chanserv/suspend chanserv/topic chanserv/status + * + * chanserv/saset/bantype chanserv/saset/description chanserv/saset/email chanserv/saset/entrymsg + * chanserv/saset/founder chanserv/saset/keeptopic chanserv/saset/mlock chanserv/saset/opnotice + * chanserv/saset/peace chanserv/saset/persist chansev/saset/private chanserv/saset/restricted + * chanserv/saset/secure chanserv/saset/securefounder chanserv/saset/secureops + * chanserv/saset/signkick chanserv/saset/successor chanserv/saset/topiclock + * chanserv/saset/url chanserv/saset/xop * - * memoserv/sendall memoserv/staff + * memoserv/sendall memoserv/staff * - * nickserv/getpass nickserv/sendpass nickserv/getemail nickserv/suspend + * nickserv/getpass nickserv/sendpass nickserv/getemail nickserv/suspend * nickserv/resetpass + * + * nickserv/saset/autoop nickserv/saset/email nickserv/saset/greet + * nickserv/saset/icq nickserv/saset/kill nickserv/saset/language nickserv/saset/message + * nickserv/saset/private nickserv/saset/secure nickserv/saset/url nickserv/saset/noexpire * * hostserv/set - Can add/modify/delete any vhost * * operserv/global operserv/news operserv/stats operserv/kick * operserv/mode operserv/session operserv/modlist operserv/ignore - * operserv/chankill operserv/akill operserv/sqline operserv/sgline + * operserv/chankill operserv/akill operserv/sqline operserv/snline * operserv/szline operserv/clearmodes operserv/staff operserv/defcon * operserv/modload operserv/jupe operserv/set operserv/noop * operserv/quit operserv/update operserv/reload operserv/restart @@ -610,29 +627,49 @@ options * Below are some default example types, but this is by no means exhaustive, * and it is recommended that you configure them to your liking. */ + opertype { - // The name of this opertype - name = "Services Root" + /* The name of this opertype */ + name = "Helper" - // What commands (see above) this opertype may use - commands = "*" + /* What privs (see above) this opertype has */ + privs = "hostserv/set" +} - // What privs (see above) this opertype has - privs = "*" +opertype +{ + /* The name of this opertype */ + name = "Services Operator" + + /* What opertype(s) this inherits from. Seperate with a comma. */ + inherits = "Helper, Another Helper" + + /* What commands (see above) this opertype may use */ + commands = "chanserv/list chanserv/suspend chanserv/status chanserv/topic memoserv/staff nickserv/sendpass nickserv/resetpass nickserv/suspend operserv/mode operserv/chankill operserv/szline operserv/akill operserv/session operserv/clearmodes operserv/modlist operserv/sqline operserv/staff operserv/kick operserv/ignore operserv/snline" + + /* What privs (see above) this opertype has */ + privs = "chanserv/auspex chanserv/no-register-limit memoserv/* nickserv/auxpex nickserv/confirm" } opertype { name = "Services Administrator" - commands = "operserv/global operserv/news operserv/stats operserv/kick operserv/mode operserv/session operserv/modlist operserv/ignore operserv/chankill operserv/akill operserv/sqline operserv/sgline operserv/szline operserv/clearmodes operserv/staff operserv/defcon botserv/* chanserv/* nickserv/* memoserv/*" + + inherits = "Services Operator" + + commands = "chanserv/access/list chanserv/drop chanserv/forbid chansev/getkey chanserv/getkey chanserv/set/noexpire memoserv/sendall nickserv/saset/* nickserv/getemail operserv/global operserv/news operserv/jupe operserv/svsnick operserv/stats operserv/oline operserv/defcon operserv/noop operserv/umode" + privs = "*" } opertype { - name = "Helper" - privs = "hostserv/set" + name = "Services Root" + + commands = "*" + + privs = "*" } /* @@ -644,26 +681,27 @@ opertype * * As with all permissions, make sure to only give trustworthy people access to Services. */ -#oper -#{ -# // The nickname of this services oper -# name = "DukePyrolator" -# -# // The opertype this person will have -# type = "Services Root" -#}# -# -#oper -#{ -# name = "nick1" -# type = "Services Administrator" -#}# -# -#oper -#{ -# name = "nick2" -# type = "Helper" -#} + +oper +{ + /* The nickname of this services oper */ + //name = "nick1" + + /* The opertype this person will have */ + type = "Services Root" +} + +oper +{ + //name = "nick2" + type = "Services Administrator" +} + +oper +{ + //name = "nick3" + type = "Helper" +} /* * [OPTIONAL] Mail Config @@ -754,7 +792,7 @@ nickserv * The core modules to load for NickServ. This is a space separated list that corresponds * to the base names of the modules for NickServ. This directive is optional, but highly recommended. */ - modules = "ns_help ns_register ns_group ns_identify ns_access ns_set ns_saset ns_drop ns_recover ns_release ns_sendpass ns_ghost ns_alist ns_info ns_list ns_logout ns_status ns_update ns_getpass ns_getemail ns_forbid ns_suspend ns_resetpass" + modules = "ns_help ns_register ns_group ns_identify ns_access ns_set ns_saset ns_set_autoop ns_set_email ns_set_greet ns_set_icq ns_set_kill ns_set_language ns_set_message ns_set_private ns_set_secure ns_set_url ns_saset_noexpire ns_drop ns_recover ns_release ns_sendpass ns_ghost ns_alist ns_info ns_list ns_logout ns_status ns_update ns_getpass ns_getemail ns_forbid ns_suspend ns_resetpass" /* * Force users to give an e-mail address when they register a nick. This directive @@ -929,7 +967,7 @@ chanserv * The core modules to load for ChanServ. This is a space separated list that corresponds * to the base names of the modules for ChanServ. This directive is optional, but highly recommended. */ - modules = "cs_help cs_register cs_set cs_xop cs_access cs_akick cs_drop cs_ban cs_clear cs_modes cs_getkey cs_invite cs_kick cs_list cs_topic cs_info forbid cs_suspend cs_status cs_unban" + modules = "cs_help cs_register cs_set cs_saset cs_set_bantype cs_set_description cs_set_email cs_set_entrymsg cs_set_founder cs_set_keeptopic cs_set_mlock cs_set_opnotice cs_set_peace cs_set_persist cs_set_private cs_set_restricted cs_set_secure cs_set_securefounder cs_set_secureops cs_set_signkick cs_set_successor cs_set_topiclock cs_set_url cs_set_xop cs_xop cs_access cs_akick cs_drop cs_ban cs_clear cs_modes cs_getkey cs_invite cs_kick cs_list cs_topic cs_info forbid cs_suspend cs_status cs_unban" /* * The default options for newly registered channels. Note that changing these options @@ -1236,7 +1274,7 @@ operserv * The core modules to load for OperServ. This is a space separated list that corresponds * to the base names of the modules for OperServ. This directive is optional, but highly recommended. */ - modules = "os_help os_global os_stats os_staff os_mode os_kick os_clearmodes os_akill os_sgline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_umode os_modload os_modunload os_modlist os_modinfo" + modules = "os_help os_global os_stats os_staff os_mode os_kick os_clearmodes os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_umode os_modload os_modunload os_modlist os_modinfo" /* * If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant @@ -1252,12 +1290,12 @@ operserv logmaxusers = yes /* - * These define the default expiration times for, respectively, AKILLs, CHANKILLs, SGLINEs, + * These define the default expiration times for, respectively, AKILLs, CHANKILLs, SNLINEs, * SQLINEs, and SZLINEs. */ autokillexpiry = 30d chankillexpiry = 30d - sglineexpiry = 30d + snlineexpiry = 30d sqlineexpiry = 30d szlineexpiry = 30d @@ -1269,11 +1307,11 @@ operserv #akillonadd = yes /* - * If set, this option will make Services send an (SVS)KILL command immediately after SGLINE ADD. - * This eliminates the need for killingthe user after the SGLINE has been added. This directive + * If set, this option will make Services send an (SVS)KILL command immediately after SNLINE ADD. + * This eliminates the need for killingthe user after the SNLINE has been added. This directive * is optional. */ - #killonsgline = yes + #killonsnline = yes /* * If set, this option will make Services send an (SVS)KILL command immediately after SQLINE ADD. @@ -1293,13 +1331,13 @@ operserv * - osclearmodes: OperServ's CLEARMODES command was used * - oskick: OperServ's KICK command was used * - osakill: OperServ's AKILL command was used - * - ossgline: OperServ's SGLINE command was used + * - ossnline: OperServ's SNLINE command was used * - ossqline: OperServ's SQLINE command was used * - osszline: OperServ's SZLINE command was used * - osnoop: OperServ's NOOP command was used * - osjupe: OperServ's JUPE command was used * - akillexpire: An AKILL has expired - * - sglineexpire: An SGLINE has expired + * - snlineexpire: An SNLINE has expired * - sqlineexpire: An SQLINE has expired * - szlineexpire: An SZLINE has expired * - exceptionexpire: A session exception has expired @@ -1312,7 +1350,7 @@ operserv * * This directive is optional, if left blank, there will be no notifications. */ - notifications="osglobal osmode osclearmodes oskick osakill ossgline ossqline osszline osnoop osjupe getpass setpass forbid drop" + notifications="osglobal osmode osclearmodes oskick osakill ossnline ossqline osszline osnoop osjupe getpass setpass forbid drop" /* * Enables session limiting. Session limiting prevents users from connecting more than a certain @@ -1507,6 +1545,13 @@ module { name = "os_info" } module { name = "hs_request" } /* + * m_ssl + * + * This module uses SSL to connect to the uplink server(s) + */ +module { name = "m_ssl" } + +/* * [OPTIONAL] Module-Specific Options * * The following blocks are used for options pertaining to modules and are not part of the core. diff --git a/data/tables.sql b/data/tables.sql index 23ba0ca50..deeef41cc 100644 --- a/data/tables.sql +++ b/data/tables.sql @@ -322,7 +322,7 @@ CREATE TABLE anope_os_core ( maxusercnt int(11) NOT NULL default '0', maxusertime int(10) unsigned NOT NULL default '0', akills_count int(11) NOT NULL default '0', - sglines_count int(11) NOT NULL default '0', + snlines_count int(11) NOT NULL default '0', sqlines_count int(11) NOT NULL default '0', szlines_count int(11) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -346,11 +346,11 @@ CREATE TABLE anope_os_exceptions ( -- -------------------------------------------------------- -- --- Table structure for table 'anope_os_sxlines' +-- Table structure for table 'anope_os_xlines' -- -DROP TABLE IF EXISTS anope_os_sxlines; -CREATE TABLE anope_os_sxlines ( +DROP TABLE IF EXISTS anope_os_xlines; +CREATE TABLE anope_os_xlines ( type varchar(20) NOT NULL, mask varchar(255) NOT NULL, xby text NOT NULL, diff --git a/docs/Changes b/docs/Changes index 0e9cca93d..c296d382a 100644 --- a/docs/Changes +++ b/docs/Changes @@ -1,5 +1,13 @@ Anope Version 1.9.3 -------------------- +A Tell users when their nicks expire in /ns glist and /ns info +A Added SSL support +A Added official support for InspIRCd 2.0 +A Prevent negaitve mode changes, kicks, bans, and autokicks from affecting people with the 'god' user mode (On UnrealIRCd, usermode +q) +A Added nickserv/auxpex permission +A Added nickserv ungroup command +A Renamed the SGLINE to be SNLINE +A Added /chanserv saset command Anope Version 1.9.2 -------------------- diff --git a/docs/Changes.conf b/docs/Changes.conf index 5420f66fd..e4ee68fd0 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -1,6 +1,22 @@ Anope Version 1.9.3 -------------------- +------------------ +** ADDED CONFIGURATION DIRECTIVES ** +nickserv/auspex privilege added +SSL module added for SSL support +opertype:inherits added to allow opertypes to inherit commands and privs from other opertypes +Various nickserv/saset/* and chanserv/saset/* opertype command privileges added +nickserv:modules added many new ns_set_command modules +chanserv:modules added many new cs_set_command modules +opertype:commands added nickserv/saset/* and chanserv/saset/* +** MODIFIED CONFIGURATION DIRECTIVES ** +opertype:commands changed operserv/sgline to opserv/snline +operserv:modules changed os_sgline to os_snline +operserv:sglineexpiry changed to operserv:snlineexpiry +operserv:killonsgline changed to operserv:killonsnline +operserv:notifications ossgline changed ossnline + +** DELETED CONFIGURATION DIRECTIVES ** Anope Version 1.9.2 -------------------- diff --git a/docs/Changes.lang b/docs/Changes.lang index ea711a609..1f75bae03 100644 --- a/docs/Changes.lang +++ b/docs/Changes.lang @@ -1,6 +1,105 @@ Anope Version 1.9.3 -------------------- +-------------------- +*** New Strings: + NICK_GLIST_REPLY_NOEXPIRE + NICK_SERVADMIN_HELP_INFO + NICK_UNGROUP_ONE_NICK + NICK_UNGROUP_NOT_IN_GROUP + NICK_UNGROUP_SUCCESSFUL + NICK_UNGROUP_SUCCESSFUL + NICK_HELP_CMD_UNGROUP + NICK_REG_MAIL + NICK_MAIL_TEXT + NICK_SENDPASS + CHAN_LEVEL_FOUNDER + OPER_STATS_SNLINE_COUNT + OPER_STATS_SNLINE_EXPIRE_DAY + OPER_STATS_SNLINE_EXPIRE_HOURS + OPER_STATS_SNLINE_EXPIRE_MINS + OPER_STATS_SNLINE_EXPIRE_MIN + OPER_STATS_SNLINE_EXPIRE_NONE + OPER_SNLINE_SYNTAX + OPER_SNLINE_UNSUPPORTED + OPER_SNLINE_EXISTS + OPER_SNLINE_ALREADY_COVERED + OPER_SNLINE_REACHED_LIMIT + OPER_SNLINE_ADDED + OPER_SNLINE_CHANGED + OPER_SNLINE_NOT_FOUND + OPER_SNLINE_NO_MATCH + OPER_SNLINE_DELETED + OPER_SNLINE_DELETED_ONE + OPER_SNLINE_DELETED_SEVERAL + OPER_SNLINE_LIST_EMPTY + OPER_SNLINE_LIST_HEADER + OPER_SNLINE_LIST_FORMAT + OPER_SNLINE_VIEW_HEADER + OPER_SNLINE_CLEAR + OPER_HELP_CMD_SNLINE + OPER_HELP_SNLINE + CHAN_SASET_SYNTAX + CHAN_SASET_KEEPTOPIC_SYNTAX + CHAN_SASET_OPNOTICE_SYNTAX + CHAN_SASET_PEACE + CHAN_SASET_PERSIST + CHAN_SASET_PRIVATE + CHAN_SASET_RESTIRCTED + CHAN_SASET_SECURE + CHAN_SASET_SECUREFOUNDER + CHAN_SASET_SECUREOPS + CHAN_SASET_SIGNKICK + CHAN_SASET_TOPICLOCK + CHAN_SASET_XOP + CHAN_HELP_CMD_SASET + CHAN_HELP_CMD_SASET_HEAD + +*** Mod Strings: + NICK_GLIST_REPLY + NICK_RESETPASS_MESSAGE +*** Del Strings: + NICK_GLIST_REPLY_ADMIN + NICK_REG_MAIL_HEAD + NICK_REG_MAIL_LINE_1 + NICK_REG_MAIL_LINE_2 + NICK_REG_MAIL_LINE_3 + NICK_REG_MAIL_LINE_4 + NICK_REG_MAIL_LINE_5 + MEMO_MAIL_TEXT1 + MEMO_MAIL_TEXT2 + MEMO_MAIL_TEXT3 + NICK_SENDPASS_HEAD + NICK_SENDPASS_HEAD_1 + NICK_SENDPASS_HEAD_2 + NICK_SENDPASS_HEAD_3 + NICK_SENDPASS_HEAD_4 + NICK_SENDPASS_HEAD_5 + OPER_STATS_SGLINE_COUNT + OPER_STATS_SGLINE_EXPIRE_DAY + OPER_STATS_SGLINE_EXPIRE_HOURS + OPER_STATS_SGLINE_EXPIRE_MINS + OPER_STATS_SGLINE_EXPIRE_MIN + OPER_STATS_SGLINE_EXPIRE_NONE + OPER_SGLINE_SYNTAX + OPER_SGLINE_UNSUPPORTED + OPER_SGLINE_EXISTS + OPER_SGLINE_ALREADY_COVERED + OPER_SGLINE_REACHED_LIMIT + OPER_SGLINE_ADDED + OPER_SGLINE_CHANGED + OPER_SGLINE_NOT_FOUND + OPER_SGLINE_NO_MATCH + OPER_SGLINE_DELETED + OPER_SGLINE_DELETED_ONE + OPER_SGLINE_DELETED_SEVERAL + OPER_SGLINE_LIST_EMPTY + OPER_SGLINE_LIST_HEADER + OPER_SGLINE_LIST_FORMAT + OPER_SGLINE_VIEW_HEADER + OPER_SGLINE_CLEAR + OPER_HELP_CMD_SGLINE + OPER_HELP_SGLINE + CHAN_SERVADMIN_HELP_SET Anope Version 1.9.2 -------------------- @@ -85,7 +85,7 @@ How To Add IRCd Support 6) VHOST: Can a user's host be changed on the fly? Enabling this allow
HostServ online. Use 1 for yes, 0 for no.
- 7) SGLINE: Does the IRCd support realname (geocs) bans? Use 1 for yes,
+ 7) SNLINE: Does the IRCd support realname (geocs) bans? Use 1 for yes,
0 for no.
8) SQLINE: Does the IRCd support nick bans? Use 1 for yes, 0 for no.
@@ -172,7 +172,7 @@ How To Add IRCd Support 35) SVSMODE UCMODE: Can we clear user channel modes with SVSMODE? Use
1 for yes, 0 for no.
- 36) SGline Enforce: Does the IRCd enforce SGLINES for us or do we need to
+ 36) SGline Enforce: Does the IRCd enforce SNLINES for us or do we need to
do so? Use 1 for yes, 0 for no.
37) Vhost Character: The character used to represent the vHost mode, if
diff --git a/docs/WIN32.txt b/docs/WIN32.txt index c9035dfd0..102c36702 100644 --- a/docs/WIN32.txt +++ b/docs/WIN32.txt @@ -25,28 +25,20 @@ Anope for Windows (NOTE: When installing, tell CMake to add itself to the PATH.)
- If you have Visual C++ 6, 7 (.NET 2002/2003), 8 (2005), or 9 (2008) skip ahead to step 2, else you
+ If you have Visual C++ 10 (2010) skip ahead to step 2, else you
need to download the following free components from Microsoft. Once
downloaded, install these packages.
- * Microsoft Visual C++ 2008 Express Edition:
+ * Microsoft Visual C++ 2010 Express Edition:
http://www.microsoft.com/express/vc/
or
- * Microsoft Visual C++ 2005 Express Edition:
- http://www.microsoft.com/downloads/details.aspx?FamilyId=7B0B0339-613A-46E6-AB4D-080D4D4A8C4E&displaylang=en
-
then download and install:
* Microsoft Windows 2008 SDK:
http://www.microsoft.com/downloads/details.aspx?FamilyId=E6E1C3DF-A74F-4207-8586-711EBE331CDC&displaylang=en
- or (if you prefer a smaller download)
-
- * Microsoft Windows 2003 Platform SDK: (Requires WGA validation)
- http://www.microsoft.com/downloads/details.aspx?FamilyId=0BAF2B35-C656-4969-ACE8-E4C0C0716ADB&displaylang=en
-
(NOTE: Although they say for Windows Server 2003 or 2008, they do infact work on all supported
versions of Windows. When installing the 2003 SDK, you should select the Custom option, and only select
to have the Microsoft Windows Core SDK installed. When installing the 2008 SDK, you should select the
@@ -54,10 +46,6 @@ Anope for Windows the Visual C++ Compilers as well as the Mobile Tools. Doing this will decrease the install time as well
as the space used by the SDK.)
- If you chose to download the 2003 SDK, it will not work out-of-the-box on either Visual C++ 2005 Express or
- Visual C++ 2008 Express. The 2008 SDK will work out-of-the-box with Visual C++ 2008 Express but not with
- Visual C++ 2005 Express.
-
2) Unpack the Anope tarball with your favorite uncompression program
(WinZip or WinRAR, etc).
diff --git a/empty.c b/empty.c deleted file mode 100644 index e69de29bb..000000000 --- a/empty.c +++ /dev/null diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 19bbcfc6c..de44e4f28 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -8,7 +8,7 @@ if(MSVC OR NOT SH) # Generate version.h from the above executable and the version.log file from the main source directory, with dependencies to the given headers and all source files in the main Anope build add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h COMMAND version_sh ${Anope_SOURCE_DIR}/version.log ${CMAKE_CURRENT_SOURCE_DIR}/version.sh ${CMAKE_CURRENT_BINARY_DIR}/version.h - MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/version.sh DEPENDS version_sh ${CMAKE_CURRENT_SOURCE_DIR}/services.h ${CMAKE_CURRENT_SOURCE_DIR}/pseudo.h ${CMAKE_CURRENT_SOURCE_DIR}/messages.h ${SRC_SRCS} + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/version.sh DEPENDS version_sh ${CMAKE_CURRENT_SOURCE_DIR}/services.h ${SRC_SRCS} ) # Add version_sh to list of files for CPack to ignore get_target_property(version_sh_BINARY version_sh LOCATION) @@ -19,7 +19,7 @@ else(MSVC OR NOT SH) # Generate version.h from version.sh and the version.log file from the main source directory, with dependencies to the given headers and all source files in the main Anope build add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.h COMMAND ${SH} ${CMAKE_CURRENT_SOURCE_DIR}/version.sh ${Anope_SOURCE_DIR}/version.log ${CMAKE_CURRENT_BINARY_DIR}/version.h - MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/version.sh DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/services.h ${CMAKE_CURRENT_SOURCE_DIR}/pseudo.h ${CMAKE_CURRENT_SOURCE_DIR}/messages.h ${SRC_SRCS} + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/version.sh DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/services.h ${SRC_SRCS} ) endif(MSVC OR NOT SH) diff --git a/include/Makefile b/include/Makefile index 3d8067aa6..de32199d3 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,18 +1,12 @@ -all: services.h extern.h pseudo.h version.h +all: services.h extern.h version.h -version.h: Makefile version.sh services.h pseudo.h messages.h $(SRCS) +version.h: Makefile version.sh services.h $(SRCS) sh version.sh ../version.log $@ services.h: sysconf.h config.h extern.h touch $@ -extern.h: slist.h - touch $@ - -pseudo.h: commands.h timers.h slist.h - touch $@ - clean: (rm -f language.h) diff --git a/include/account.h b/include/account.h index 004760699..e44880c29 100644 --- a/include/account.h +++ b/include/account.h @@ -1,3 +1,14 @@ +class NickAlias; +class NickCore; +class NickRequest; + +typedef unordered_map_namespace::unordered_map<ci::string, NickAlias *, hash_compare_ci_string> nickalias_map; +typedef unordered_map_namespace::unordered_map<ci::string, NickCore *, hash_compare_ci_string> nickcore_map; +typedef unordered_map_namespace::unordered_map<ci::string, NickRequest *, hash_compare_ci_string> nickrequest_map; + +extern CoreExport nickalias_map NickAliasList; +extern CoreExport nickcore_map NickCoreList; +extern CoreExport nickrequest_map NickRequestList; /* NickServ nickname structures. */ @@ -69,16 +80,13 @@ enum NickCoreFlag NI_END }; -/** XXX: this really needs to die with fire and be merged with metadata into NickCore or something. - */ -class CoreExport NickRequest +class CoreExport NickRequest : public Extensible { public: NickRequest(const std::string &nickname); ~NickRequest(); - NickRequest *next, *prev; char *nick; std::string passcode; std::string password; @@ -102,7 +110,6 @@ class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag> */ ~NickAlias(); - NickAlias *next, *prev; char *nick; /* Nickname */ char *last_quit; /* Last quit message */ char *last_realname; /* Last realname */ @@ -137,8 +144,6 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag> */ ~NickCore(); - NickCore *next, *prev; - std::list<User *> Users; char *display; /* How the nick is displayed */ @@ -156,7 +161,7 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag> /* Unsaved data */ time_t lastmail; /* Last time this nick record got a mail */ - SList aliases; /* List of aliases */ + std::list<NickAlias *> aliases; /* List of aliases */ /** Check whether this opertype has access to run the given command string. * @param cmdstr The string to check, e.g. botserv/set/private. diff --git a/include/bots.h b/include/bots.h index 3b4987bb7..8952005e7 100644 --- a/include/bots.h +++ b/include/bots.h @@ -8,6 +8,15 @@ * */ +#include "commands.h" + +class BotInfo; + +typedef unordered_map_namespace::unordered_map<ci::string, BotInfo *, hash_compare_ci_string> botinfo_map; +typedef unordered_map_namespace::unordered_map<std::string, BotInfo *, hash_compare_std_string> botinfo_uid_map; +extern CoreExport botinfo_map BotListByNick; +extern CoreExport botinfo_uid_map BotListByUID; + /** Flags settable on a bot */ enum BotFlag @@ -16,29 +25,13 @@ enum BotFlag /* This bot can only be assigned by IRCops */ BI_PRIVATE, - /* The following flags are used to determin what bot really is what. - * Since you *could* have ChanServ really named BotServ or something stupid, - * this keeps track of them and allows them to be renamed in the config - * at any time, even if they already exist in the database - */ - BI_CHANSERV, - BI_BOTSERV, - BI_HOSTSERV, - BI_OPERSERV, - BI_MEMOSERV, - BI_NICKSERV, - BI_GLOBAL, BI_END }; -struct CommandHash; - class CoreExport BotInfo : public Extensible, public Flags<BotFlag> { public: - BotInfo *next, *prev; - std::string uid; /* required for UID supporting servers, as opposed to the shitty struct Uid. */ std::string nick; /* Nickname of the bot */ std::string user; /* Its user name */ @@ -48,7 +41,7 @@ class CoreExport BotInfo : public Extensible, public Flags<BotFlag> int16 chancount; /* Number of channels that use the bot. */ /* Dynamic data */ time_t lastmsg; /* Last time we said something */ - CommandHash **cmdTable; + CommandMap Commands; /** Create a new bot. * @param nick The nickname to assign to the bot. diff --git a/include/channels.h b/include/channels.h index 51b830c03..7814a377a 100644 --- a/include/channels.h +++ b/include/channels.h @@ -8,6 +8,9 @@ * */ +typedef unordered_map_namespace::unordered_map<ci::string, Channel *, hash_compare_ci_string> channel_map; +extern CoreExport channel_map ChannelList; + struct UserData { UserData() @@ -59,7 +62,7 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> std::map<ChannelModeName, std::string> Params; /* Modes set on the channel */ - std::bitset<128> modes; + Flags<ChannelModeName> modes; public: /** Default constructor @@ -72,7 +75,6 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> */ ~Channel(); - Channel *next, *prev; std::string name; /* Channel name */ ChannelInfo *ci; /* Corresponding ChannelInfo */ time_t creation_time; /* When channel was created */ @@ -134,7 +136,7 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> /** See if the channel has any modes at all * @return true or false */ - inline const bool HasModes() const { return modes.count(); } + inline const bool HasModes() const { return modes.FlagCount(); } /** See if a channel has a mode * @param Name The mode name diff --git a/include/commands.h b/include/commands.h index d139fa01a..327d65736 100644 --- a/include/commands.h +++ b/include/commands.h @@ -11,17 +11,108 @@ * */ - #include "modules.h" +#ifndef COMMAND_H_ +#define COMMAND_H_ -/*************************************************************************/ +#include "services.h" -/* Routines for looking up commands. Command lists are arrays that must be - * terminated with a NULL name. +class Module; +class BotInfo; +class Command; + +typedef std::map<ci::string, Command *> CommandMap; + +/** The return value from commands. + */ +enum CommandReturn +{ + MOD_CONT, + MOD_STOP +}; + +extern CoreExport Command *FindCommand(BotInfo *bi, const ci::string &cmd); +extern CoreExport void mod_help_cmd(BotInfo *bi, User *u, const ci::string &cmd); +extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, const std::string &message); +extern CoreExport void mod_run_cmd(BotInfo *bi, User *u, Command *c, const ci::string &command, const ci::string &message); + +enum CommandFlag +{ + CFLAG_ALLOW_UNREGISTERED, + CFLAG_ALLOW_FORBIDDEN, + CFLAG_ALLOW_SUSPENDED, + CFLAG_ALLOW_UNREGISTEREDCHANNEL, + CFLAG_STRIP_CHANNEL, + CFLAG_DISABLE_FANTASY +}; + +/** Every services command is a class, inheriting from Command. */ +class CoreExport Command : public Flags<CommandFlag> +{ + public: + /* Maximum paramaters accepted by this command */ + size_t MaxParams; + /* Minimum parameters required to use this command */ + size_t MinParams; + /* Command name */ + ci::string name; + /* Permission needed to use this comand */ + std::string permission; + + /* Module which owns us */ + Module *module; + /* Service this command is on */ + BotInfo *service; + + /** Create a new command. + * @param sname The command name + * @param min_params The minimum number of parameters the parser will require to execute this command + * @param max_params The maximum number of parameters the parser will create, after max_params, all will be combined into the last argument. + * NOTE: If max_params is not set (default), there is no limit to the max number of params. + */ + Command(const ci::string &sname, size_t min_params, size_t max_params = 0, const std::string &spermission = ""); + + virtual ~Command(); + + /** Execute this command. + * @param u The user executing the command. + */ + virtual CommandReturn Execute(User *u, const std::vector<ci::string> &); + + /** Called when HELP is requsted for the client this command is on. + * @param u The user requesting help + */ + virtual void OnServHelp(User *u); + + /** Requested when the user is requesting help on this command. Help on this command should be sent to the user. + * @param u The user requesting help + * @param subcommand The subcommand the user is requesting help on, or an empty string. (e.g. /ns help set foo bar lol gives a subcommand of +"FOO BAR LOL") + * @return true if help was provided to the user, false otherwise. + */ + virtual bool OnHelp(User *u, const ci::string &subcommand); + + /** Requested when the user provides bad syntax to this command (not enough params, etc). + * @param u The user executing the command. + * @param subcommand The subcommand the user tried to use + */ + virtual void OnSyntaxError(User *u, const ci::string &subcommand); + + /** Set which command permission (e.g. chanserv/forbid) is required for this command. + * @param reststr The permission required to successfully execute this command + */ + void SetPermission(const std::string &reststr); + + /** Add a subcommand to this command + * @param c The command + */ + virtual bool AddSubcommand(Command *c); + + /** Delete a subcommand from this command + * @param cname The subcommand name + */ + virtual bool DelSubcommand(const ci::string &cname); +}; -extern MDE Command *lookup_cmd(Command *list, char *name); -extern MDE void mod_help_cmd(char *service, User *u, CommandHash *cmdTable[], const char *cmd); -extern MDE void mod_run_cmd(const std::string &service, User *u, CommandHash *cmdTable[], const char *cmd); -//extern MDE void do_help_limited(char *service, User * u, Command * c); +#endif -/*************************************************************************/ diff --git a/include/config.h b/include/config.h index 825cc9af4..dacf3db06 100644 --- a/include/config.h +++ b/include/config.h @@ -1,39 +1,903 @@ -/* Services configuration. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * +#ifndef _CONFIGREADER_H_ +#define _CONFIGREADER_H_ + +#include <string> +#include <fstream> +#include <sstream> +#include <vector> +#include <map> +#include <deque> + +/** A configuration key and value pair + */ +typedef std::pair<std::string, std::string> KeyVal; + +/** A list of related configuration keys and values + */ +typedef std::vector<KeyVal> KeyValList; + +/** An entire config file, built up of KeyValLists + */ +typedef std::multimap<std::string, KeyValList> ConfigDataHash; + +// Required forward definitions +class ServerConfig; + +/** Types of data in the core config + */ +enum ConfigDataType { + DT_NOTHING, // No data + DT_INTEGER, // Integer + DT_UINTEGER, // Unsigned Integer + DT_LUINTEGER, // Long Unsigned Integer + DT_CHARPTR, // Char pointer + DT_STRING, // std::string + DT_BOOLEAN, // Boolean + DT_HOSTNAME, // Hostname syntax + DT_NOSPACES, // No spaces + DT_IPADDRESS, // IP address (v4, v6) + DT_TIME, // Time value + DT_NORELOAD = 32, // Item can't be reloaded after startup + DT_ALLOW_WILD = 64, // Allow wildcards/CIDR in DT_IPADDRESS + DT_ALLOW_NEWLINE = 128 // New line characters allowed in DT_CHARPTR +}; + +/** Holds a config value, either string, integer or boolean. + * Callback functions receive one or more of these, either on + * their own as a reference, or in a reference to a deque of them. + * The callback function can then alter the values of the ValueItem + * classes to validate the settings. + */ +class ValueItem +{ + /** Actual data */ + std::string v; + public: + /** Initialize with an int */ + ValueItem(int); + /** Initialize with a bool */ + ValueItem(bool); + /** Initialize with a char pointer */ + ValueItem(const char *); + /** Initialize with an std::string */ + ValueItem(const std::string &); + /** Initialize with a long */ + ValueItem(long); + /** Change value to a char pointer */ + //void Set(char *); + /** Change value to a const char pointer */ + void Set(const char *); + /** Change value to an std::string */ + void Set(const std::string &); + /** Change value to an int */ + void Set(int); + /** Get value as an int */ + int GetInteger(); + /** Get value as a string */ + const char *GetString() const; + /** Get value as a string */ + inline const std::string &GetValue() const { return v; } + /** Get value as a bool */ + bool GetBool(); +}; + +/** The base class of the container 'ValueContainer' + * used internally by the core to hold core values. + */ +class ValueContainerBase +{ + public: + /** Constructor */ + ValueContainerBase() { } + /** Destructor */ + virtual ~ValueContainerBase() { } +}; + +/** ValueContainer is used to contain pointers to different + * core values such as the server name, maximum number of + * clients etc. + * It is specialized to hold a data type, then pointed at + * a value in the ServerConfig class. When the value has been + * read and validated, the Set method is called to write the + * value safely in a type-safe manner. + */ +template<typename T> class ValueContainer : public ValueContainerBase +{ + /** Contained item */ + T val; + public: + /** Initialize with nothing */ + ValueContainer() : ValueContainerBase(), val(NULL) { } + /** Initialize with a value of type T */ + ValueContainer(T Val) : ValueContainerBase(), val(Val) { } + /** Initialize with a copy */ + ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } + ValueContainer &operator=(const ValueContainer &Val) + { + val = Val.val; + return *this; + } + /** Change value to type T of size s */ + void Set(const T newval, size_t s) + { + memcpy(val, newval, s); + } +}; + +/** This a specific version of ValueContainer to handle character arrays specially + */ +template<> class ValueContainer<char **> : public ValueContainerBase +{ + /** Contained item */ + char **val; + public: + /** Initialize with nothing */ + ValueContainer() : ValueContainerBase(), val(NULL) { } + /** Initialize with a value of type T */ + ValueContainer(char **Val) : ValueContainerBase(), val(Val) { } + /** Initialize with a copy */ + ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } + ValueContainer &operator=(const ValueContainer &Val) + { + val = Val.val; + return *this; + } + /** Change value to type T of size s */ + void Set(const char *newval, size_t s) + { + if (*val) delete [] *val; + if (!*newval) { + *val = NULL; + return; + } + *val = new char[s]; + strlcpy(*val, newval, s); + } +}; + +/** This a specific version of ValueContainer to handle std::string specially + */ +template<> class ValueContainer<std::string *> : public ValueContainerBase +{ + /** Contained item */ + std::string *val; + public: + /** Initialize with nothing */ + ValueContainer() : ValueContainerBase(), val(NULL) { } + /** Initialize with an std::string */ + ValueContainer(std::string *Val) : ValueContainerBase(), val(Val) { } + /** Initialize with a copy */ + ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } + ValueContainer &operator=(const ValueContainer &Val) + { + val = Val.val; + return *this; + } + /** Change value to given std::string */ + void Set(const std::string &newval) + { + *val = newval; + } + /** Change value to given char pointer */ + void Set(const char *newval) + { + *val = newval; + } +}; + +/** A specialization of ValueContainer to hold a pointer to a bool + */ +typedef ValueContainer<bool *> ValueContainerBool; + +/** A specialization of ValueContainer to hold a pointer to + * an unsigned int + */ +typedef ValueContainer<unsigned *> ValueContainerUInt; + +/** A specialization of ValueContainer to hold a pointer to + * a long unsigned int + */ +typedef ValueContainer<long unsigned *> ValueContainerLUInt; + +/** A specialization of ValueContainer to hold a pointer to + * a char array. + */ +typedef ValueContainer<char **> ValueContainerChar; + +/** A specialization of ValueContainer to hold a pointer to + * an int + */ +typedef ValueContainer<int *> ValueContainerInt; + +/** A specialization of ValueContainer to hold a pointer to + * a time_t + */ +typedef ValueContainer<time_t *> ValueContainerTime; + +/** A specialization of ValueContainer to hold a pointer to + * an std::string + */ +typedef ValueContainer<std::string *> ValueContainerString; + +/** A set of ValueItems used by multi-value validator functions + */ +typedef std::deque<ValueItem> ValueList; + +/** A callback for validating a single value + */ +typedef bool (*Validator)(ServerConfig *, const char *, const char *, ValueItem &); +/** A callback for validating multiple value entries + */ +typedef bool (*MultiValidator)(ServerConfig *, const char *, const char **, ValueList &, int *, bool); +/** A callback indicating the end of a group of entries + */ +typedef bool (*MultiNotify)(ServerConfig *, const char *, bool); + +/** Holds a core configuration item and its callbacks + */ +struct InitialConfig +{ + /** Tag name */ + const char *tag; + /** Value name */ + const char *value; + /** Default, if not defined */ + const char *default_value; + /** Value containers */ + ValueContainerBase *val; + /** Data types */ + int datatype; + /** Validation function */ + Validator validation_function; +}; + +/** Holds a core configuration item and its callbacks + * where there may be more than one item + */ +struct MultiConfig +{ + /** Tag name */ + const char *tag; + /** One or more items within tag */ + const char *items[17]; + /** One or more defaults for items within tags */ + const char *items_default[17]; + /** One or more data types */ + int datatype[17]; + /** Initialization function */ + MultiNotify init_function; + /** Validation function */ + MultiValidator validation_function; + /** Completion function */ + MultiNotify finish_function; +}; + +/** This class holds the bulk of the runtime configuration for the ircd. + * It allows for reading new config values, accessing configuration files, + * and storage of the configuration data needed to run the ircd, such as + * the servername, connect classes, /ADMIN data, MOTDs and filenames etc. */ +class ServerConfig +{ + private: + /** This variable holds the names of all + * files included from the main one. This + * is used to make sure that no files are + * recursively included. + */ + std::vector<std::string> include_stack; + /** Check that there is only one of each configuration item + */ + bool CheckOnce(const char *); + public: + std::ostringstream errstr; + ConfigDataHash newconfig; + /** This holds all the information in the config file, + * it's indexed by tag name to a vector of key/values. + */ + ConfigDataHash config_data; + /** Construct a new ServerConfig + */ + ServerConfig(); + /** Clears the include stack in preperation for a Read() call. + */ + void ClearStack(); + /** Read the entire configuration into memory + * and initialize this class. All other methods + * should be used only by the core. + */ + int Read(bool); + /** Report a configuration error given in errormessage. + * @param bail If this is set to true, the error is sent to the console, and the program exits + * @param connection If this is set to a non-null value, and bail is false, the errors are spooled to + * this connection as SNOTICEs. + * If the parameter is NULL, the messages are spooled to all connections via WriteOpers as SNOTICEs. + */ + void ReportConfigError(const std::string &, bool); + /** Load 'filename' into 'target', with the new config parser everything is parsed into + * tag/key/value at load-time rather than at read-value time. + */ + bool LoadConf(ConfigDataHash &, const char *, std::ostringstream &); + /** Load 'filename' into 'target', with the new config parser everything is parsed into + * tag/key/value at load-time rather than at read-value time. + */ + bool LoadConf(ConfigDataHash &, const std::string &, std::ostringstream &); + // Both these return true if the value existed or false otherwise + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &, const char *, const char *, int, char *, int, bool = false); + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &, const char *, const char *, const char *, int, char *, int, bool = false); + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &, const std::string &, const std::string &, int, std::string &, bool = false); + /** Writes 'length' chars into 'result' as a string + */ + bool ConfValue(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int, std::string &, bool = false); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &, const char *, const char *, int, int &); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &, const char *, const char *, const char *, int, int &); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &, const std::string &, const std::string &, int, int &); + /** Tries to convert the value to an integer and write it to 'result' + */ + bool ConfValueInteger(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int, int &); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &, const char *, const char *, int); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &, const char *, const char *, const char *, int); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &, const std::string &, const std::string &, int); + /** Returns true if the value exists and has a true value, false otherwise + */ + bool ConfValueBool(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int); + /** Returns the number of occurences of tag in the config file + */ + int ConfValueEnum(ConfigDataHash &, const char *); + /** Returns the number of occurences of tag in the config file + */ + int ConfValueEnum(ConfigDataHash &, const std::string &); + /** Returns the numbers of vars inside the index'th 'tag in the config file + */ + int ConfVarEnum(ConfigDataHash &, const char *, int); + /** Returns the numbers of vars inside the index'th 'tag in the config file + */ + int ConfVarEnum(ConfigDataHash &, const std::string &, int); + void ValidateHostname(const char *, const std::string &, const std::string &); + void ValidateIP(const char *p, const std::string &, const std::string &, bool); + void ValidateNoSpaces(const char *, const std::string &, const std::string &); + + + + /** Below here is a list of variables which contain the config files values + */ + /* IRCd module in use */ + char *IRCDModule; -#ifndef CONFIG_H -#define CONFIG_H + /* Host to connect to **/ + char *LocalHost; + /* List of uplink servers to try and connect to */ + std::list<Uplink *> Uplinks; -/* Note that most of the options which used to be here have been moved to - * services.conf. */ + /* Our server name */ + char *ServerName; + /* Our servers description */ + char *ServerDesc; + /* The username/ident of services clients */ + char *ServiceUser; + /* The hostname if services clients */ + char *ServiceHost; -/*************************************************************************/ + /* Help channel, ops here get usermode +h **/ + char *HelpChannel; + /* Log channel */ + char *LogChannel; + /* Name of the network were on */ + char *NetworkName; + /* The max legnth of nicks */ + unsigned NickLen; + /* Max length of idents */ + unsigned UserLen; + /* Max lenght of hostnames */ + unsigned HostLen; -/******* General configuration *******/ + /* Max length of passwords */ + unsigned PassLen; -/* Name of log file (in Services directory) */ -#define LOG_FILENAME "services.log" + /* NickServ Name */ + char *s_NickServ; + /* ChanServ Name */ + char *s_ChanServ; + /* MemoServ Name */ + char *s_MemoServ; + /* BotServ Name */ + char *s_BotServ; + /* OperServ name */ + char *s_OperServ; + /* Global name */ + char *s_GlobalNoticer; + /* NickServs realname */ + char *desc_NickServ; + /* ChanServ realname */ + char *desc_ChanServ; + /* MemoServ relname */ + char *desc_MemoServ; + /* BotServ realname */ + char *desc_BotServ; + /* OperServ realname */ + char *desc_OperServ; + /* Global realname */ + char *desc_GlobalNoticer; -/******************* END OF USER-CONFIGURABLE SECTION ********************/ + /* HostServ Name */ + char *s_HostServ; + /* HostServ realname */ + char *desc_HostServ; -/* Size of input buffer (note: this is different from BUFSIZ) - * This must be big enough to hold at least one full IRC message, or messy - * things will happen. */ -#define BUFSIZE 1024 + /* Filename for the PID file */ + char *PIDFilename; + /* MOTD filename */ + char *MOTDFilename; -/* Maximum amount of data from/to the network to buffer (bytes). */ -#define NET_BUFSIZE 65536 + /* True if its ok to not be able to save backs */ + bool NoBackupOkay; + /* Do password checking when new people register */ + bool StrictPasswords; + /* How many times you're allowed to give a bad password before being killed */ + unsigned BadPassLimit; + /* How long before bad passwords are forgotten */ + time_t BadPassTimeout; + /* Delay between automatic database updates */ + time_t UpdateTimeout; + /* Delay between checks for expired nicks and channels */ + time_t ExpireTimeout; + /* How long to wait for something from the uplink, this is passed to select() */ + time_t ReadTimeout; + /* How often to send program errors */ + time_t WarningTimeout; + /* How long to process things such as timers to see if there is anything to calll */ + time_t TimeoutCheck; + /* Num of days logfiles are kept */ + int KeepLogs; + /* Number of days backups are kept */ + int KeepBackups; + /* Forbidding requires a reason */ + bool ForceForbidReason; + /* Services should use privmsgs instead of notices */ + bool UsePrivmsg; + /* Services only respond to full PRIVMSG client@services.server.name messages */ + bool UseStrictPrivMsg; + /* Dump a core file if we crash */ + bool DumpCore; + /* Log users connecting/existing/changing nicks */ + bool LogUsers; + /* Number of seconds between consecutive uses of the REGISTER command + * Not to be confused with NSRegDelay */ + unsigned NickRegDelay; + /* Max number if news items allowed in the list */ + unsigned NewsCount; + /* Default mlock modes */ + std::string MLock; + /* Default botmodes on channels, defaults to ao */ + std::string BotModes; + /* How many times to try and reconnect to the uplink before giving up */ + unsigned MaxRetries; + /* How long to wait between connection attempts */ + int RetryWait; -/**************************************************************************/ + /* Services can use email */ + bool UseMail; + /* Path to the sendmail executable */ + char *SendMailPath; + /* Address to send from */ + char *SendFrom; + /* Only opers can have services send mail */ + bool RestrictMail; + /* Delay between sending mail */ + time_t MailDelay; + /* Don't quote the To: address */ + bool DontQuoteAddresses; + + /* Prefix of guest nicks when a user gets forced off of a nick */ + char *NSGuestNickPrefix; + /* Allow users to set kill immed on */ + bool NSAllowKillImmed; + /* Don't allow nicks to use /ns group to regroup nicks */ + bool NSNoGroupChange; + /* Default flags for newly registered nicks */ + Flags<NickCoreFlag> NSDefFlags; + /* Default language used by services */ + unsigned NSDefLanguage; + /* Users must be connected this long before they can register + * Not to be confused with NickRegDelay */ + time_t NSRegDelay; + /* Time before the registering mail will be resent */ + time_t NSResendDelay; + /* How long before nicks expir */ + time_t NSExpire; + /* Time before NickRequests expire */ + time_t NSRExpire; + /* Force email when registering */ + bool NSForceEmail; + /* Max number of nicks in a group */ + int NSMaxAliases; + /* Max number of allowed strings on the access list */ + unsigned NSAccessMax; + /* Enforcer client user name */ + char *NSEnforcerUser; + /* Enforcer client hostname */ + char *NSEnforcerHost; + /* How long before recovered nicks are released */ + time_t NSReleaseTimeout; + /* /nickserv list is oper only */ + bool NSListOpersOnly; + /* Max number of entries that can be returned from the list command */ + unsigned NSListMax; + /* Only allow usermode +a etc on real services admins */ + bool NSSecureAdmins; + /* Services opers must be /operd on the ircd aswell */ + bool NSStrictPrivileges; + /* Use email to verify new users registering */ + bool NSEmailReg; + /* Set the proper channel modes on users when they identify */ + bool NSModeOnID; + /* Add the users hostnask their access list when they register */ + bool NSAddAccessOnReg; + + /* Default flags for newly registered channels */ + Flags<ChannelInfoFlag> CSDefFlags; + /* Max number of channels a user can own */ + unsigned CSMaxReg; + /* Time before a channel expires */ + time_t CSExpire; + /* Default ban type to use for channels */ + int CSDefBantype; + /* Max number of entries allowed on channel access lists */ + unsigned CSAccessMax; + /* Max number of entries allowed on autokick lists */ + unsigned CSAutokickMax; + /* Default autokick reason */ + char *CSAutokickReason; + /* Time ChanServ should stay in the channel to hold it to keep users from getting in */ + time_t CSInhabit; + /* ChanServ's LIST command is oper only */ + bool CSListOpersOnly; + /* Max number of entries allowed to be returned from the LIST command */ + unsigned CSListMax; + /* true to make ChanServ oper only */ + bool CSOpersOnly; + + /* Max number of memos allowed */ + unsigned MSMaxMemos; + /* Time you must wait between sending memos */ + time_t MSSendDelay; + /* Notify all of the aliases of the core the memo was sent to */ + bool MSNotifyAll; + /* Who can use memos reciepts */ + unsigned MSMemoReceipt; + + /* Defai;t BotServ flags */ + Flags<BotServFlag> BSDefFlags; + /* How long before botserv forgets a user. This is used for flood kickers etc */ + time_t BSKeepData; + /* Min number of users to have in the channel before the service bot joins */ + unsigned BSMinUsers; + /* Max number of words allowed on the badwordslist */ + unsigned BSBadWordsMax; + /* BotServ bot only joins if it would normally allowed to, abides by bans etc */ + bool BSSmartJoin; + /* Dont tell users what badword they used */ + bool BSGentleBWReason; + /* Case sensitive badwords matching */ + bool BSCaseSensitive; + /* Char to use for the fantasy char, eg ! */ + char *BSFantasyCharacter; + + /* Only show /stats o to opers */ + bool HideStatsO; + /* Send out a global when services shut down or restart */ + bool GlobalOnCycle; + /* Don't include the opers name in globals */ + bool AnonymousGlobal; + /* Dont allow users to register nicks with oper names in them */ + bool RestrictOperNicks; + /* Message to send when shutting down */ + char *GlobalOnCycleMessage; + /* Message to send when starting up */ + char *GlobalOnCycleUP; + /* Super admin is allowed */ + bool SuperAdmin; + /* Log things said through ACT/SAY */ + bool LogBot; + /* Log when new user max is reached */ + bool LogMaxUsers; + /* Default expiry time for akills */ + time_t AutokillExpiry; + /* Default expiry time for chan kills */ + time_t ChankillExpiry; + /* Default expiry time for SNLine Expire */ + time_t SNLineExpiry; + /* Default expiry time for SQLines */ + time_t SQLineExpiry; + /* Default expiry time for SZLine */ + time_t SZLineExpiry; + /* Actually akill the user when the akill is added */ + bool AkillOnAdd; + /* Kill users on SNLine */ + bool KillonSNline; + /* Kill users on SQline */ + bool KillonSQline; + /* Send a WALLOPS/GLOBOPS when a user opers */ + bool WallOper; + /* Send a WALLOPS/GLOBOPS when a nonoper tries to use OperServ */ + bool WallBadOS; + /* Send a WALLOPS/GLOBOPS when someone uses the GLOBAL command */ + bool WallOSGlobal; + /* Send a WALLOPS/GLOBOPS when someone uses the MODE command */ + bool WallOSMode; + /* Send a WALLOPS/GLOBOPS when someone uses the CLEARMODES command */ + bool WallOSClearmodes; + /* Send a WALLOPS/GLOBOPS when someone uses the KICK command */ + bool WallOSKick; + /* Send a WALLOPS/GLOBOPS when someone uses the AKILL command */ + bool WallOSAkill; + /* Send a WALLOPS/GLOBOPS when someone uses the SNLINE command */ + bool WallOSSNLine; + /* Send a WALLOPS/GLOBOPS when someone uses the SQLINE command */ + bool WallOSSQLine; + /* Send a WALLOPS/GLOBOPS when someone uses the SZLINE command */ + bool WallOSSZLine; + /* Send a WALLOPS/GLOBOPS when someone uses the NOOP command */ + bool WallOSNoOp; + /* Send a WALLOPS/GLOBOPS when when someone uses the JUPE command */ + bool WallOSJupe; + /* Send a WALLOPS/GLOBOPS when an akill expires */ + bool WallAkillExpire; + /* Send a WALLOPS/GLOBOPS when SNLines expire */ + bool WallSNLineExpire; + /* Send a WALLOPS/GLOBOPS when SQLines expire */ + bool WallSQLineExpire; + /* Send a WALLOPS/GLOBOPS when SZLines expire */ + bool WallSZLineExpire; + /* Send a WALLOPS/GLOBOPS when exceptions expire */ + bool WallExceptionExpire; + /* Send a WALLOPS/GLOBOPS when DROP is used */ + bool WallDrop; + /* Send a WALLOPS/GLOBOPS when FORBID is used */ + bool WallForbid; + /* Send a WALLOPS/GLOBOPS when GETPASS is used */ + bool WallGetpass; + /* Send a WALLOPS/GLOBOPS when SETPASS is used */ + bool WallSetpass; + /* Add the akillers nick to the akill reason */ + bool AddAkiller; + + /* Limit sessions */ + bool LimitSessions; + /* The default session limit */ + unsigned DefSessionLimit; + /* How long before exceptions expire */ + time_t ExceptionExpiry; + /* How many times to kill before adding an KILL */ + int MaxSessionKill; + /* Max limit that can be used for exceptions */ + unsigned MaxSessionLimit; + /* How long session akills should last */ + time_t SessionAutoKillExpiry; + /* Reason to use for session kills */ + char *SessionLimitExceeded; + /* Optional second reason */ + char *SessionLimitDetailsLoc; + /* OperServ requires you to be an operator */ + bool OSOpersOnly; + + /* List of modules to autoload */ + std::list<std::string> ModulesAutoLoad; + /* Encryption modules */ + std::list<std::string> EncModuleList; + /* Database modules */ + std::list<std::string> DBModuleList; + /* HostServ Core Modules */ + std::list<std::string> HostServCoreModules; + /* MemoServ Core Modules */ + std::list<std::string> MemoServCoreModules; + /* BotServ Core Modules */ + std::list<std::string> BotServCoreModules; + /* OperServ Core Modules */ + std::list<std::string> OperServCoreModules; + /* NickServ Core Modules */ + std::list<std::string> NickServCoreModules; + /* ChanServ Core Modules */ + std::list<std::string> ChanServCoreModules; + + /* Default defcon level */ + int DefConLevel; + /* Timeout before defcon is reset */ + time_t DefConTimeOut; + /* Session limiit to use when using defcon */ + int DefConSessionLimit; + /* How long to add akills for defcon */ + time_t DefConAKILL; + /* Chan modes for defcon */ + char *DefConChanModes; + /* Should we global on defcon */ + bool GlobalOnDefcon; + /* Should we send DefconMessage aswell? */ + bool GlobalOnDefconMore; + /* Message to send when defcon is off */ + char *DefConOffMessage; + /* Message to send when defcon is on*/ + char *DefconMessage; + /* Reason to akill clients for defcon */ + char *DefConAkillReason; + + /* User keys to use for generating random hashes for pass codes etc */ + long unsigned int UserKey1; + long unsigned int UserKey2; + long unsigned int UserKey3; + + /* Numeric */ + char *Numeric; + /* Array of ulined servers */ + char **Ulines; + /* Number of ulines */ + int NumUlines; + + /* List of available opertypes */ + std::list<OperType *> MyOperTypes; + /* List of pairs of opers and their opertype from the config */ + std::list<std::pair<std::string, std::string> > Opers; +}; + +/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. + * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or + * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not + * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user + * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time. + */ +class ConfigException : public CoreException +{ + public: + /** Default constructor, just uses the error mesage 'Config threw an exception'. + */ + ConfigException() : CoreException("Config threw an exception", "Config Parser") {} + /** This constructor can be used to specify an error message before throwing. + */ + ConfigException(const std::string &message) : CoreException(message, "Config Parser") {} + /** This destructor solves world hunger, cancels the world debt, and causes the world to end. + * Actually no, it does nothing. Never mind. + * @throws Nothing! + */ + virtual ~ConfigException() throw() { }; +}; + +#define CONF_NO_ERROR 0x000000 +#define CONF_NOT_A_NUMBER 0x000010 +#define CONF_INT_NEGATIVE 0x000080 +#define CONF_VALUE_NOT_FOUND 0x000100 +#define CONF_FILE_NOT_FOUND 0x000200 + +/** Allows reading of values from configuration files + * This class allows a module to read from either the main configuration file (inspircd.conf) or from + * a module-specified configuration file. It may either be instantiated with one parameter or none. + * Constructing the class using one parameter allows you to specify a path to your own configuration + * file, otherwise, inspircd.conf is read. + */ +class CoreExport ConfigReader +{ + protected: + /** The contents of the configuration file + * This protected member should never be accessed by a module (and cannot be accessed unless the + * core is changed). It will contain a pointer to the configuration file data with unneeded data + * (such as comments) stripped from it. + */ + ConfigDataHash *data; + /** Used to store errors + */ + std::ostringstream *errorlog; + /** If we're using our own config data hash or not + */ + bool privatehash; + /** True if an error occured reading the config file + */ + bool readerror; + /** Error code + */ + long error; + public: + /** Default constructor. + * This constructor initialises the ConfigReader class to read services.conf. + */ + ConfigReader(); + /** Overloaded constructor. + * This constructor initialises the ConfigReader class to read a user-specified config file + */ + ConfigReader(const std::string &); + /** Default destructor. + * This method destroys the ConfigReader class. + */ + ~ConfigReader(); + /** Retrieves a value from the config file. + * This method retrieves a value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. + */ + std::string ReadValue(const std::string &, const std::string &, int, bool = false); + /** Retrieves a value from the config file. + * This method retrieves a value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. If the + * tag is not found the default value is returned instead. + */ + std::string ReadValue(const std::string &, const std::string &, const std::string &, int, bool = false); + /** Retrieves a boolean value from the config file. + * This method retrieves a boolean value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes" + * and "true" in the config file count as true to ReadFlag, and any other value counts as false. + */ + bool ReadFlag(const std::string &, const std::string &, int); + /** Retrieves a boolean value from the config file. + * This method retrieves a boolean value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes" + * and "true" in the config file count as true to ReadFlag, and any other value counts as false. + * If the tag is not found, the default value is used instead. + */ + bool ReadFlag(const std::string &, const std::string &, const std::string &, int); + /** Retrieves an integer value from the config file. + * This method retrieves an integer value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. Any invalid integer + * values in the tag will cause the objects error value to be set, and any call to GetError() will + * return CONF_INVALID_NUMBER to be returned. need_positive is set if the number must be non-negative. + * If a negative number is placed into a tag which is specified positive, 0 will be returned and GetError() + * will return CONF_INT_NEGATIVE. Note that need_positive is not suitable to get an unsigned int - you + * should cast the result to achieve that effect. + */ + int ReadInteger(const std::string &, const std::string &, int, bool); + /** Retrieves an integer value from the config file. + * This method retrieves an integer value from the config file. Where multiple copies of the tag + * exist in the config file, index indicates which of the values to retrieve. Any invalid integer + * values in the tag will cause the objects error value to be set, and any call to GetError() will + * return CONF_INVALID_NUMBER to be returned. needs_unsigned is set if the number must be unsigned. + * If a signed number is placed into a tag which is specified unsigned, 0 will be returned and GetError() + * will return CONF_NOT_UNSIGNED. If the tag is not found, the default value is used instead. + */ + int ReadInteger(const std::string &, const std::string &, const std::string &, int, bool); + /** Returns the last error to occur. + * Valid errors can be found by looking in modules.h. Any nonzero value indicates an error condition. + * A call to GetError() resets the error flag back to 0. + */ + long GetError(); + /** Counts the number of times a given tag appears in the config file. + * This method counts the number of times a tag appears in a config file, for use where + * there are several tags of the same kind, e.g. with opers and connect types. It can be + * used with the index value of ConfigReader::ReadValue to loop through all copies of a + * multiple instance tag. + */ + int Enumerate(const std::string &); + /** Returns true if a config file is valid. + * This method is partially implemented and will only return false if the config + * file does not exist or could not be opened. + */ + bool Verify(); + /** Dumps the list of errors in a config file to an output location. If bail is true, + * then the program will abort. If bail is false and user points to a valid user + * record, the error report will be spooled to the given user by means of NOTICE. + * if bool is false AND user is false, the error report will be spooled to all opers + * by means of a NOTICE to all opers. + */ + void DumpErrors(bool); + /** Returns the number of items within a tag. + * For example if the tag was <test tag="blah" data="foo"> then this + * function would return 2. Spaces and newlines both qualify as valid seperators + * between values. + */ + int EnumerateValues(const std::string &, int); +}; -#endif /* CONFIG_H */ +#endif diff --git a/include/configreader.h b/include/configreader.h deleted file mode 100644 index 7015eab99..000000000 --- a/include/configreader.h +++ /dev/null @@ -1,903 +0,0 @@ -#ifndef _CONFIGREADER_H_ -#define _CONFIGREADER_H_ - -#include <string> -#include <fstream> -#include <sstream> -#include <vector> -#include <map> -#include <deque> - -/** A configuration key and value pair - */ -typedef std::pair<std::string, std::string> KeyVal; - -/** A list of related configuration keys and values - */ -typedef std::vector<KeyVal> KeyValList; - -/** An entire config file, built up of KeyValLists - */ -typedef std::multimap<std::string, KeyValList> ConfigDataHash; - -// Required forward definitions -class ServerConfig; - -/** Types of data in the core config - */ -enum ConfigDataType { - DT_NOTHING, // No data - DT_INTEGER, // Integer - DT_UINTEGER, // Unsigned Integer - DT_LUINTEGER, // Long Unsigned Integer - DT_CHARPTR, // Char pointer - DT_STRING, // std::string - DT_BOOLEAN, // Boolean - DT_HOSTNAME, // Hostname syntax - DT_NOSPACES, // No spaces - DT_IPADDRESS, // IP address (v4, v6) - DT_TIME, // Time value - DT_NORELOAD = 32, // Item can't be reloaded after startup - DT_ALLOW_WILD = 64, // Allow wildcards/CIDR in DT_IPADDRESS - DT_ALLOW_NEWLINE = 128 // New line characters allowed in DT_CHARPTR -}; - -/** Holds a config value, either string, integer or boolean. - * Callback functions receive one or more of these, either on - * their own as a reference, or in a reference to a deque of them. - * The callback function can then alter the values of the ValueItem - * classes to validate the settings. - */ -class ValueItem -{ - /** Actual data */ - std::string v; - public: - /** Initialize with an int */ - ValueItem(int); - /** Initialize with a bool */ - ValueItem(bool); - /** Initialize with a char pointer */ - ValueItem(const char *); - /** Initialize with an std::string */ - ValueItem(const std::string &); - /** Initialize with a long */ - ValueItem(long); - /** Change value to a char pointer */ - //void Set(char *); - /** Change value to a const char pointer */ - void Set(const char *); - /** Change value to an std::string */ - void Set(const std::string &); - /** Change value to an int */ - void Set(int); - /** Get value as an int */ - int GetInteger(); - /** Get value as a string */ - const char *GetString() const; - /** Get value as a string */ - inline const std::string &GetValue() const { return v; } - /** Get value as a bool */ - bool GetBool(); -}; - -/** The base class of the container 'ValueContainer' - * used internally by the core to hold core values. - */ -class ValueContainerBase -{ - public: - /** Constructor */ - ValueContainerBase() { } - /** Destructor */ - virtual ~ValueContainerBase() { } -}; - -/** ValueContainer is used to contain pointers to different - * core values such as the server name, maximum number of - * clients etc. - * It is specialized to hold a data type, then pointed at - * a value in the ServerConfig class. When the value has been - * read and validated, the Set method is called to write the - * value safely in a type-safe manner. - */ -template<typename T> class ValueContainer : public ValueContainerBase -{ - /** Contained item */ - T val; - public: - /** Initialize with nothing */ - ValueContainer() : ValueContainerBase(), val(NULL) { } - /** Initialize with a value of type T */ - ValueContainer(T Val) : ValueContainerBase(), val(Val) { } - /** Initialize with a copy */ - ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } - ValueContainer &operator=(const ValueContainer &Val) - { - val = Val.val; - return *this; - } - /** Change value to type T of size s */ - void Set(const T newval, size_t s) - { - memcpy(val, newval, s); - } -}; - -/** This a specific version of ValueContainer to handle character arrays specially - */ -template<> class ValueContainer<char **> : public ValueContainerBase -{ - /** Contained item */ - char **val; - public: - /** Initialize with nothing */ - ValueContainer() : ValueContainerBase(), val(NULL) { } - /** Initialize with a value of type T */ - ValueContainer(char **Val) : ValueContainerBase(), val(Val) { } - /** Initialize with a copy */ - ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } - ValueContainer &operator=(const ValueContainer &Val) - { - val = Val.val; - return *this; - } - /** Change value to type T of size s */ - void Set(const char *newval, size_t s) - { - if (*val) delete [] *val; - if (!*newval) { - *val = NULL; - return; - } - *val = new char[s]; - strlcpy(*val, newval, s); - } -}; - -/** This a specific version of ValueContainer to handle std::string specially - */ -template<> class ValueContainer<std::string *> : public ValueContainerBase -{ - /** Contained item */ - std::string *val; - public: - /** Initialize with nothing */ - ValueContainer() : ValueContainerBase(), val(NULL) { } - /** Initialize with an std::string */ - ValueContainer(std::string *Val) : ValueContainerBase(), val(Val) { } - /** Initialize with a copy */ - ValueContainer(const ValueContainer &Val) : ValueContainerBase(), val(Val.val) { } - ValueContainer &operator=(const ValueContainer &Val) - { - val = Val.val; - return *this; - } - /** Change value to given std::string */ - void Set(const std::string &newval) - { - *val = newval; - } - /** Change value to given char pointer */ - void Set(const char *newval) - { - *val = newval; - } -}; - -/** A specialization of ValueContainer to hold a pointer to a bool - */ -typedef ValueContainer<bool *> ValueContainerBool; - -/** A specialization of ValueContainer to hold a pointer to - * an unsigned int - */ -typedef ValueContainer<unsigned *> ValueContainerUInt; - -/** A specialization of ValueContainer to hold a pointer to - * a long unsigned int - */ -typedef ValueContainer<long unsigned *> ValueContainerLUInt; - -/** A specialization of ValueContainer to hold a pointer to - * a char array. - */ -typedef ValueContainer<char **> ValueContainerChar; - -/** A specialization of ValueContainer to hold a pointer to - * an int - */ -typedef ValueContainer<int *> ValueContainerInt; - -/** A specialization of ValueContainer to hold a pointer to - * a time_t - */ -typedef ValueContainer<time_t *> ValueContainerTime; - -/** A specialization of ValueContainer to hold a pointer to - * an std::string - */ -typedef ValueContainer<std::string *> ValueContainerString; - -/** A set of ValueItems used by multi-value validator functions - */ -typedef std::deque<ValueItem> ValueList; - -/** A callback for validating a single value - */ -typedef bool (*Validator)(ServerConfig *, const char *, const char *, ValueItem &); -/** A callback for validating multiple value entries - */ -typedef bool (*MultiValidator)(ServerConfig *, const char *, const char **, ValueList &, int *, bool); -/** A callback indicating the end of a group of entries - */ -typedef bool (*MultiNotify)(ServerConfig *, const char *, bool); - -/** Holds a core configuration item and its callbacks - */ -struct InitialConfig -{ - /** Tag name */ - const char *tag; - /** Value name */ - const char *value; - /** Default, if not defined */ - const char *default_value; - /** Value containers */ - ValueContainerBase *val; - /** Data types */ - int datatype; - /** Validation function */ - Validator validation_function; -}; - -/** Holds a core configuration item and its callbacks - * where there may be more than one item - */ -struct MultiConfig -{ - /** Tag name */ - const char *tag; - /** One or more items within tag */ - const char *items[17]; - /** One or more defaults for items within tags */ - const char *items_default[17]; - /** One or more data types */ - int datatype[17]; - /** Initialization function */ - MultiNotify init_function; - /** Validation function */ - MultiValidator validation_function; - /** Completion function */ - MultiNotify finish_function; -}; - -/** This class holds the bulk of the runtime configuration for the ircd. - * It allows for reading new config values, accessing configuration files, - * and storage of the configuration data needed to run the ircd, such as - * the servername, connect classes, /ADMIN data, MOTDs and filenames etc. - */ -class ServerConfig -{ - private: - /** This variable holds the names of all - * files included from the main one. This - * is used to make sure that no files are - * recursively included. - */ - std::vector<std::string> include_stack; - /** Check that there is only one of each configuration item - */ - bool CheckOnce(const char *); - public: - std::ostringstream errstr; - ConfigDataHash newconfig; - /** This holds all the information in the config file, - * it's indexed by tag name to a vector of key/values. - */ - ConfigDataHash config_data; - /** Construct a new ServerConfig - */ - ServerConfig(); - /** Clears the include stack in preperation for a Read() call. - */ - void ClearStack(); - /** Read the entire configuration into memory - * and initialize this class. All other methods - * should be used only by the core. - */ - int Read(bool); - /** Report a configuration error given in errormessage. - * @param bail If this is set to true, the error is sent to the console, and the program exits - * @param connection If this is set to a non-null value, and bail is false, the errors are spooled to - * this connection as SNOTICEs. - * If the parameter is NULL, the messages are spooled to all connections via WriteOpers as SNOTICEs. - */ - void ReportConfigError(const std::string &, bool); - /** Load 'filename' into 'target', with the new config parser everything is parsed into - * tag/key/value at load-time rather than at read-value time. - */ - bool LoadConf(ConfigDataHash &, const char *, std::ostringstream &); - /** Load 'filename' into 'target', with the new config parser everything is parsed into - * tag/key/value at load-time rather than at read-value time. - */ - bool LoadConf(ConfigDataHash &, const std::string &, std::ostringstream &); - // Both these return true if the value existed or false otherwise - /** Writes 'length' chars into 'result' as a string - */ - bool ConfValue(ConfigDataHash &, const char *, const char *, int, char *, int, bool = false); - /** Writes 'length' chars into 'result' as a string - */ - bool ConfValue(ConfigDataHash &, const char *, const char *, const char *, int, char *, int, bool = false); - /** Writes 'length' chars into 'result' as a string - */ - bool ConfValue(ConfigDataHash &, const std::string &, const std::string &, int, std::string &, bool = false); - /** Writes 'length' chars into 'result' as a string - */ - bool ConfValue(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int, std::string &, bool = false); - /** Tries to convert the value to an integer and write it to 'result' - */ - bool ConfValueInteger(ConfigDataHash &, const char *, const char *, int, int &); - /** Tries to convert the value to an integer and write it to 'result' - */ - bool ConfValueInteger(ConfigDataHash &, const char *, const char *, const char *, int, int &); - /** Tries to convert the value to an integer and write it to 'result' - */ - bool ConfValueInteger(ConfigDataHash &, const std::string &, const std::string &, int, int &); - /** Tries to convert the value to an integer and write it to 'result' - */ - bool ConfValueInteger(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int, int &); - /** Returns true if the value exists and has a true value, false otherwise - */ - bool ConfValueBool(ConfigDataHash &, const char *, const char *, int); - /** Returns true if the value exists and has a true value, false otherwise - */ - bool ConfValueBool(ConfigDataHash &, const char *, const char *, const char *, int); - /** Returns true if the value exists and has a true value, false otherwise - */ - bool ConfValueBool(ConfigDataHash &, const std::string &, const std::string &, int); - /** Returns true if the value exists and has a true value, false otherwise - */ - bool ConfValueBool(ConfigDataHash &, const std::string &, const std::string &, const std::string &, int); - /** Returns the number of occurences of tag in the config file - */ - int ConfValueEnum(ConfigDataHash &, const char *); - /** Returns the number of occurences of tag in the config file - */ - int ConfValueEnum(ConfigDataHash &, const std::string &); - /** Returns the numbers of vars inside the index'th 'tag in the config file - */ - int ConfVarEnum(ConfigDataHash &, const char *, int); - /** Returns the numbers of vars inside the index'th 'tag in the config file - */ - int ConfVarEnum(ConfigDataHash &, const std::string &, int); - void ValidateHostname(const char *, const std::string &, const std::string &); - void ValidateIP(const char *p, const std::string &, const std::string &, bool); - void ValidateNoSpaces(const char *, const std::string &, const std::string &); - - - - /** Below here is a list of variables which contain the config files values - */ - /* IRCd module in use */ - char *IRCDModule; - - /* Host to connect to **/ - char *LocalHost; - /* List of uplink servers to try and connect to */ - std::list<Uplink *> Uplinks; - - /* Our server name */ - char *ServerName; - /* Our servers description */ - char *ServerDesc; - /* The username/ident of services clients */ - char *ServiceUser; - /* The hostname if services clients */ - char *ServiceHost; - - /* Help channel, ops here get usermode +h **/ - char *HelpChannel; - /* Log channel */ - char *LogChannel; - /* Name of the network were on */ - char *NetworkName; - /* The max legnth of nicks */ - unsigned NickLen; - /* Max length of idents */ - unsigned UserLen; - /* Max lenght of hostnames */ - unsigned HostLen; - - /* Max length of passwords */ - unsigned PassLen; - - /* NickServ Name */ - char *s_NickServ; - /* ChanServ Name */ - char *s_ChanServ; - /* MemoServ Name */ - char *s_MemoServ; - /* BotServ Name */ - char *s_BotServ; - /* OperServ name */ - char *s_OperServ; - /* Global name */ - char *s_GlobalNoticer; - /* NickServs realname */ - char *desc_NickServ; - /* ChanServ realname */ - char *desc_ChanServ; - /* MemoServ relname */ - char *desc_MemoServ; - /* BotServ realname */ - char *desc_BotServ; - /* OperServ realname */ - char *desc_OperServ; - /* Global realname */ - char *desc_GlobalNoticer; - - /* HostServ Name */ - char *s_HostServ; - /* HostServ realname */ - char *desc_HostServ; - - /* Filename for the PID file */ - char *PIDFilename; - /* MOTD filename */ - char *MOTDFilename; - - /* True if its ok to not be able to save backs */ - bool NoBackupOkay; - /* Do password checking when new people register */ - bool StrictPasswords; - /* How many times you're allowed to give a bad password before being killed */ - unsigned BadPassLimit; - /* How long before bad passwords are forgotten */ - time_t BadPassTimeout; - /* Delay between automatic database updates */ - time_t UpdateTimeout; - /* Delay between checks for expired nicks and channels */ - time_t ExpireTimeout; - /* How long to wait for something from the uplink, this is passed to select() */ - time_t ReadTimeout; - /* How often to send program errors */ - time_t WarningTimeout; - /* How long to process things such as timers to see if there is anything to calll */ - time_t TimeoutCheck; - /* Num of days logfiles are kept */ - int KeepLogs; - /* Number of days backups are kept */ - int KeepBackups; - /* Forbidding requires a reason */ - bool ForceForbidReason; - /* Services should use privmsgs instead of notices */ - bool UsePrivmsg; - /* Services only respond to full PRIVMSG client@services.server.name messages */ - bool UseStrictPrivMsg; - /* Dump a core file if we crash */ - bool DumpCore; - /* Log users connecting/existing/changing nicks */ - bool LogUsers; - /* Number of seconds between consecutive uses of the REGISTER command - * Not to be confused with NSRegDelay */ - unsigned NickRegDelay; - /* Max number if news items allowed in the list */ - unsigned NewsCount; - /* Default mlock modes */ - std::string MLock; - /* Default botmodes on channels, defaults to ao */ - std::string BotModes; - /* How many times to try and reconnect to the uplink before giving up */ - unsigned MaxRetries; - /* How long to wait between connection attempts */ - int RetryWait; - - /* Services can use email */ - bool UseMail; - /* Path to the sendmail executable */ - char *SendMailPath; - /* Address to send from */ - char *SendFrom; - /* Only opers can have services send mail */ - bool RestrictMail; - /* Delay between sending mail */ - time_t MailDelay; - /* Don't quote the To: address */ - bool DontQuoteAddresses; - - /* Prefix of guest nicks when a user gets forced off of a nick */ - char *NSGuestNickPrefix; - /* Allow users to set kill immed on */ - bool NSAllowKillImmed; - /* Don't allow nicks to use /ns group to regroup nicks */ - bool NSNoGroupChange; - /* Default flags for newly registered nicks */ - Flags<NickCoreFlag> NSDefFlags; - /* Default language used by services */ - unsigned NSDefLanguage; - /* Users must be connected this long before they can register - * Not to be confused with NickRegDelay */ - time_t NSRegDelay; - /* Time before the registering mail will be resent */ - time_t NSResendDelay; - /* How long before nicks expir */ - time_t NSExpire; - /* Time before NickRequests expire */ - time_t NSRExpire; - /* Force email when registering */ - bool NSForceEmail; - /* Max number of nicks in a group */ - int NSMaxAliases; - /* Max number of allowed strings on the access list */ - unsigned NSAccessMax; - /* Enforcer client user name */ - char *NSEnforcerUser; - /* Enforcer client hostname */ - char *NSEnforcerHost; - /* How long before recovered nicks are released */ - time_t NSReleaseTimeout; - /* /nickserv list is oper only */ - bool NSListOpersOnly; - /* Max number of entries that can be returned from the list command */ - unsigned NSListMax; - /* Only allow usermode +a etc on real services admins */ - bool NSSecureAdmins; - /* Services opers must be /operd on the ircd aswell */ - bool NSStrictPrivileges; - /* Use email to verify new users registering */ - bool NSEmailReg; - /* Set the proper channel modes on users when they identify */ - bool NSModeOnID; - /* Add the users hostnask their access list when they register */ - bool NSAddAccessOnReg; - - /* Default flags for newly registered channels */ - Flags<ChannelInfoFlag> CSDefFlags; - /* Max number of channels a user can own */ - unsigned CSMaxReg; - /* Time before a channel expires */ - time_t CSExpire; - /* Default ban type to use for channels */ - int CSDefBantype; - /* Max number of entries allowed on channel access lists */ - unsigned CSAccessMax; - /* Max number of entries allowed on autokick lists */ - unsigned CSAutokickMax; - /* Default autokick reason */ - char *CSAutokickReason; - /* Time ChanServ should stay in the channel to hold it to keep users from getting in */ - time_t CSInhabit; - /* ChanServ's LIST command is oper only */ - bool CSListOpersOnly; - /* Max number of entries allowed to be returned from the LIST command */ - unsigned CSListMax; - /* true to make ChanServ oper only */ - bool CSOpersOnly; - - /* Max number of memos allowed */ - unsigned MSMaxMemos; - /* Time you must wait between sending memos */ - time_t MSSendDelay; - /* Notify all of the aliases of the core the memo was sent to */ - bool MSNotifyAll; - /* Who can use memos reciepts */ - unsigned MSMemoReceipt; - - /* Defai;t BotServ flags */ - Flags<BotServFlag> BSDefFlags; - /* How long before botserv forgets a user. This is used for flood kickers etc */ - time_t BSKeepData; - /* Min number of users to have in the channel before the service bot joins */ - unsigned BSMinUsers; - /* Max number of words allowed on the badwordslist */ - unsigned BSBadWordsMax; - /* BotServ bot only joins if it would normally allowed to, abides by bans etc */ - bool BSSmartJoin; - /* Dont tell users what badword they used */ - bool BSGentleBWReason; - /* Case sensitive badwords matching */ - bool BSCaseSensitive; - /* Char to use for the fantasy char, eg ! */ - char *BSFantasyCharacter; - - /* Only show /stats o to opers */ - bool HideStatsO; - /* Send out a global when services shut down or restart */ - bool GlobalOnCycle; - /* Don't include the opers name in globals */ - bool AnonymousGlobal; - /* Dont allow users to register nicks with oper names in them */ - bool RestrictOperNicks; - /* Message to send when shutting down */ - char *GlobalOnCycleMessage; - /* Message to send when starting up */ - char *GlobalOnCycleUP; - /* Super admin is allowed */ - bool SuperAdmin; - /* Log things said through ACT/SAY */ - bool LogBot; - /* Log when new user max is reached */ - bool LogMaxUsers; - /* Default expiry time for akills */ - time_t AutokillExpiry; - /* Default expiry time for chan kills */ - time_t ChankillExpiry; - /* Default expiry time for SGLine Expire */ - time_t SGLineExpiry; - /* Default expiry time for SQLines */ - time_t SQLineExpiry; - /* Default expiry time for SZLine */ - time_t SZLineExpiry; - /* Actually akill the user when the akill is added */ - bool AkillOnAdd; - /* Kill users on SGline */ - bool KillonSGline; - /* Kill users on SQline */ - bool KillonSQline; - /* Send a WALLOPS/GLOBOPS when a user opers */ - bool WallOper; - /* Send a WALLOPS/GLOBOPS when a nonoper tries to use OperServ */ - bool WallBadOS; - /* Send a WALLOPS/GLOBOPS when someone uses the GLOBAL command */ - bool WallOSGlobal; - /* Send a WALLOPS/GLOBOPS when someone uses the MODE command */ - bool WallOSMode; - /* Send a WALLOPS/GLOBOPS when someone uses the CLEARMODES command */ - bool WallOSClearmodes; - /* Send a WALLOPS/GLOBOPS when someone uses the KICK command */ - bool WallOSKick; - /* Send a WALLOPS/GLOBOPS when someone uses the AKILL command */ - bool WallOSAkill; - /* Send a WALLOPS/GLOBOPS when someone uses the SGLINE command */ - bool WallOSSGLine; - /* Send a WALLOPS/GLOBOPS when someone uses the SQLINE command */ - bool WallOSSQLine; - /* Send a WALLOPS/GLOBOPS when someone uses the SZLINE command */ - bool WallOSSZLine; - /* Send a WALLOPS/GLOBOPS when someone uses the NOOP command */ - bool WallOSNoOp; - /* Send a WALLOPS/GLOBOPS when when someone uses the JUPE command */ - bool WallOSJupe; - /* Send a WALLOPS/GLOBOPS when an akill expires */ - bool WallAkillExpire; - /* Send a WALLOPS/GLOBOPS when SGLines expire */ - bool WallSGLineExpire; - /* Send a WALLOPS/GLOBOPS when SQLines expire */ - bool WallSQLineExpire; - /* Send a WALLOPS/GLOBOPS when SZLines expire */ - bool WallSZLineExpire; - /* Send a WALLOPS/GLOBOPS when exceptions expire */ - bool WallExceptionExpire; - /* Send a WALLOPS/GLOBOPS when DROP is used */ - bool WallDrop; - /* Send a WALLOPS/GLOBOPS when FORBID is used */ - bool WallForbid; - /* Send a WALLOPS/GLOBOPS when GETPASS is used */ - bool WallGetpass; - /* Send a WALLOPS/GLOBOPS when SETPASS is used */ - bool WallSetpass; - /* Add the akillers nick to the akill reason */ - bool AddAkiller; - - /* Limit sessions */ - bool LimitSessions; - /* The default session limit */ - unsigned DefSessionLimit; - /* How long before exceptions expire */ - time_t ExceptionExpiry; - /* How many times to kill before adding an KILL */ - int MaxSessionKill; - /* Max limit that can be used for exceptions */ - unsigned MaxSessionLimit; - /* How long session akills should last */ - time_t SessionAutoKillExpiry; - /* Reason to use for session kills */ - char *SessionLimitExceeded; - /* Optional second reason */ - char *SessionLimitDetailsLoc; - /* OperServ requires you to be an operator */ - bool OSOpersOnly; - - /* List of modules to autoload */ - std::list<std::string> ModulesAutoLoad; - /* Encryption modules */ - std::list<std::string> EncModuleList; - /* Database modules */ - std::list<std::string> DBModuleList; - /* HostServ Core Modules */ - std::list<std::string> HostServCoreModules; - /* MemoServ Core Modules */ - std::list<std::string> MemoServCoreModules; - /* BotServ Core Modules */ - std::list<std::string> BotServCoreModules; - /* OperServ Core Modules */ - std::list<std::string> OperServCoreModules; - /* NickServ Core Modules */ - std::list<std::string> NickServCoreModules; - /* ChanServ Core Modules */ - std::list<std::string> ChanServCoreModules; - - /* Default defcon level */ - int DefConLevel; - /* Timeout before defcon is reset */ - time_t DefConTimeOut; - /* Session limiit to use when using defcon */ - int DefConSessionLimit; - /* How long to add akills for defcon */ - time_t DefConAKILL; - /* Chan modes for defcon */ - char *DefConChanModes; - /* Should we global on defcon */ - bool GlobalOnDefcon; - /* Should we send DefconMessage aswell? */ - bool GlobalOnDefconMore; - /* Message to send when defcon is off */ - char *DefConOffMessage; - /* Message to send when defcon is on*/ - char *DefconMessage; - /* Reason to akill clients for defcon */ - char *DefConAkillReason; - - /* User keys to use for generating random hashes for pass codes etc */ - long unsigned int UserKey1; - long unsigned int UserKey2; - long unsigned int UserKey3; - - /* Numeric */ - char *Numeric; - /* Array of ulined servers */ - char **Ulines; - /* Number of ulines */ - int NumUlines; - - /* List of available opertypes */ - std::list<OperType *> MyOperTypes; - /* List of pairs of opers and their opertype from the config */ - std::list<std::pair<std::string, std::string> > Opers; -}; - -/** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. - * When a module whishes to abort, e.g. within a constructor, it should throw an exception using ModuleException or - * a class derived from ModuleException. If a module throws an exception during its constructor, the module will not - * be loaded. If this happens, the error message returned by ModuleException::GetReason will be displayed to the user - * attempting to load the module, or dumped to the console if the ircd is currently loading for the first time. - */ -class ConfigException : public CoreException -{ - public: - /** Default constructor, just uses the error mesage 'Config threw an exception'. - */ - ConfigException() : CoreException("Config threw an exception", "Config Parser") {} - /** This constructor can be used to specify an error message before throwing. - */ - ConfigException(const std::string &message) : CoreException(message, "Config Parser") {} - /** This destructor solves world hunger, cancels the world debt, and causes the world to end. - * Actually no, it does nothing. Never mind. - * @throws Nothing! - */ - virtual ~ConfigException() throw() { } -}; - -#define CONF_NO_ERROR 0x000000 -#define CONF_NOT_A_NUMBER 0x000010 -#define CONF_INT_NEGATIVE 0x000080 -#define CONF_VALUE_NOT_FOUND 0x000100 -#define CONF_FILE_NOT_FOUND 0x000200 - -/** Allows reading of values from configuration files - * This class allows a module to read from either the main configuration file (inspircd.conf) or from - * a module-specified configuration file. It may either be instantiated with one parameter or none. - * Constructing the class using one parameter allows you to specify a path to your own configuration - * file, otherwise, inspircd.conf is read. - */ -class CoreExport ConfigReader -{ - protected: - /** The contents of the configuration file - * This protected member should never be accessed by a module (and cannot be accessed unless the - * core is changed). It will contain a pointer to the configuration file data with unneeded data - * (such as comments) stripped from it. - */ - ConfigDataHash *data; - /** Used to store errors - */ - std::ostringstream *errorlog; - /** If we're using our own config data hash or not - */ - bool privatehash; - /** True if an error occured reading the config file - */ - bool readerror; - /** Error code - */ - long error; - public: - /** Default constructor. - * This constructor initialises the ConfigReader class to read services.conf. - */ - ConfigReader(); - /** Overloaded constructor. - * This constructor initialises the ConfigReader class to read a user-specified config file - */ - ConfigReader(const std::string &); - /** Default destructor. - * This method destroys the ConfigReader class. - */ - ~ConfigReader(); - /** Retrieves a value from the config file. - * This method retrieves a value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. - */ - std::string ReadValue(const std::string &, const std::string &, int, bool = false); - /** Retrieves a value from the config file. - * This method retrieves a value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. If the - * tag is not found the default value is returned instead. - */ - std::string ReadValue(const std::string &, const std::string &, const std::string &, int, bool = false); - /** Retrieves a boolean value from the config file. - * This method retrieves a boolean value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes" - * and "true" in the config file count as true to ReadFlag, and any other value counts as false. - */ - bool ReadFlag(const std::string &, const std::string &, int); - /** Retrieves a boolean value from the config file. - * This method retrieves a boolean value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. The values "1", "yes" - * and "true" in the config file count as true to ReadFlag, and any other value counts as false. - * If the tag is not found, the default value is used instead. - */ - bool ReadFlag(const std::string &, const std::string &, const std::string &, int); - /** Retrieves an integer value from the config file. - * This method retrieves an integer value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. Any invalid integer - * values in the tag will cause the objects error value to be set, and any call to GetError() will - * return CONF_INVALID_NUMBER to be returned. need_positive is set if the number must be non-negative. - * If a negative number is placed into a tag which is specified positive, 0 will be returned and GetError() - * will return CONF_INT_NEGATIVE. Note that need_positive is not suitable to get an unsigned int - you - * should cast the result to achieve that effect. - */ - int ReadInteger(const std::string &, const std::string &, int, bool); - /** Retrieves an integer value from the config file. - * This method retrieves an integer value from the config file. Where multiple copies of the tag - * exist in the config file, index indicates which of the values to retrieve. Any invalid integer - * values in the tag will cause the objects error value to be set, and any call to GetError() will - * return CONF_INVALID_NUMBER to be returned. needs_unsigned is set if the number must be unsigned. - * If a signed number is placed into a tag which is specified unsigned, 0 will be returned and GetError() - * will return CONF_NOT_UNSIGNED. If the tag is not found, the default value is used instead. - */ - int ReadInteger(const std::string &, const std::string &, const std::string &, int, bool); - /** Returns the last error to occur. - * Valid errors can be found by looking in modules.h. Any nonzero value indicates an error condition. - * A call to GetError() resets the error flag back to 0. - */ - long GetError(); - /** Counts the number of times a given tag appears in the config file. - * This method counts the number of times a tag appears in a config file, for use where - * there are several tags of the same kind, e.g. with opers and connect types. It can be - * used with the index value of ConfigReader::ReadValue to loop through all copies of a - * multiple instance tag. - */ - int Enumerate(const std::string &); - /** Returns true if a config file is valid. - * This method is partially implemented and will only return false if the config - * file does not exist or could not be opened. - */ - bool Verify(); - /** Dumps the list of errors in a config file to an output location. If bail is true, - * then the program will abort. If bail is false and user points to a valid user - * record, the error report will be spooled to the given user by means of NOTICE. - * if bool is false AND user is false, the error report will be spooled to all opers - * by means of a NOTICE to all opers. - */ - void DumpErrors(bool); - /** Returns the number of items within a tag. - * For example if the tag was <test tag="blah" data="foo"> then this - * function would return 2. Spaces and newlines both qualify as valid seperators - * between values. - */ - int EnumerateValues(const std::string &, int); -}; - -#endif diff --git a/include/defs.h b/include/defs.h deleted file mode 100644 index e571b691f..000000000 --- a/include/defs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Set default values for any constants that should be in include files but - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - * - */ - -/*************************************************************************/ - -#ifndef NAME_MAX -# define NAME_MAX 255 -#endif - -#ifndef BUFSIZ -# define BUFSIZ 256 -#else -# if BUFSIZ < 256 -# define BUFSIZ 256 -# endif -#endif - -/* Length of an array: */ -#define lenof(a) (sizeof(a) / sizeof(*(a))) - -/* Telling compilers about printf()-like functions: */ -#ifdef __GNUC__ -# define FORMAT(type,fmt,start) __attribute__((format(type,fmt,start))) -#else -# define FORMAT(type,fmt,start) -#endif - -/*************************************************************************/ diff --git a/include/extern.h b/include/extern.h index 5ede04dc8..416e974e8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -17,14 +17,11 @@ #define E extern CoreExport #define EI extern DllExport -#include "slist.h" #include "hashcomp.h" E void ModuleRunTimeDirCleanUp(); -E char *uplink; - /* IRC Variables */ E IRCDVar *ircd; @@ -35,19 +32,25 @@ E IRCDProto *ircdproto; E void kill_user(const std::string &source, const std::string &user, const std::string &reason); E bool bad_password(User *u); -E void sqline(const std::string &mask, const std::string &reason); E void common_unban(ChannelInfo *ci, const std::string &nick); +E BotInfo *BotServ; +E BotInfo *ChanServ; +E BotInfo *Global; +E BotInfo *HostServ; +E BotInfo *MemoServ; +E BotInfo *NickServ; +E BotInfo *OperServ; + /**** botserv.c ****/ -E BotInfo *botlists[256]; -E int nbots; E void get_botserv_stats(long *nrec, long *memuse); E void bs_init(); -E void botserv(User *u, char *buf); -E void botmsgs(User *u, BotInfo *bi, char *buf); -E void botchanmsgs(User *u, ChannelInfo *ci, char *buf); +E void botserv(User *u, BotInfo *bi, const std::string &buf); +E void botchanmsgs(User *u, ChannelInfo *ci, const std::string &buf); +E BotInfo *findbot(const char *nick); E BotInfo *findbot(const std::string &nick); +E BotInfo *findbot(const ci::string &nick); /** Finds a pseudoclient, given a UID. Useful for TS6 protocol modules. * @param uid The UID to search for @@ -55,7 +58,6 @@ E BotInfo *findbot(const std::string &nick); */ E void bot_join(ChannelInfo *ci); E char *normalizeBuffer(const char *); -E void insert_bot(BotInfo * bi); E void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, const char *reason); E void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, const char *reason); @@ -63,12 +65,11 @@ E void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, char * /**** channels.c ****/ -E Channel *chanlist[1024]; - E void get_channel_stats(long *nrec, long *memuse); + E Channel *findchan(const char *chan); -E Channel *firstchan(); -E Channel *nextchan(); +E Channel *findchan(const std::string &chan); +E Channel *findchan(const ci::string &chan); E void ChanSetInternalModes(Channel *c, int ac, const char **av); @@ -77,6 +78,7 @@ E User *nc_on_chan(Channel * c, NickCore * nc); E char *chan_get_modes(Channel * chan, int complete, int plus); E int get_access_level(ChannelInfo * ci, NickAlias * na); +E int get_access_level(ChannelInfo *ci, NickCore *nc); E const char *get_xop_level(int level); E void do_cmode(const char *source, int ac, const char **av); @@ -106,34 +108,28 @@ E long get_memuse(EList *list); /**** chanserv.c ****/ -E ChannelInfo *chanlists[256]; E LevelInfo levelinfo[]; E void get_chanserv_stats(long *nrec, long *memuse); -E void alpha_insert_chan(ChannelInfo * ci); E void reset_levels(ChannelInfo * ci); E void cs_init(); -E void chanserv(User * u, char *buf); +E void chanserv(User *u, const std::string &buf); E void expire_chans(); E void cs_remove_nick(const NickCore * nc); E void check_modes(Channel * c); E int check_valid_admin(User * user, Channel * chan, int servermode); E int check_valid_op(User * user, Channel * chan, int servermode); -E int check_should_op(User * user, char *chan); -E int check_should_voice(User * user, char *chan); -E int check_should_halfop(User * user, char *chan); -E int check_should_owner(User * user, char *chan); -E int check_should_protect(User * user, char *chan); E void record_topic(const char *chan); E void restore_topic(const char *chan); E int check_topiclock(Channel * c, time_t topic_time); +E ChannelInfo *cs_findchan(const char *chan); E ChannelInfo *cs_findchan(const std::string &chan); +E ChannelInfo *cs_findchan(const ci::string &chan); E int check_access(User * user, ChannelInfo * ci, int what); E bool IsFounder(User *user, ChannelInfo *ci); -E bool IsRealFounder(User *user, ChannelInfo *ci); E int get_access(User *user, ChannelInfo *ci); E void update_cs_lastseen(User * user, ChannelInfo * ci); E int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen); @@ -162,7 +158,7 @@ E int read_config(int reload); /* hostserv.c */ E void do_on_id(User *u); -E void hostserv(User *u, char *buf); +E void hostserv(User *u, const std::string &buf); E void HostServSyncVhosts(NickAlias *na); /**** encrypt.c ****/ @@ -213,22 +209,12 @@ E void log_perror(const char *fmt, ...) FORMAT(printf,1,2); E void fatal(const char *fmt, ...) FORMAT(printf,1,2); E void fatal_perror(const char *fmt, ...) FORMAT(printf,1,2); -/**** mail.c ****/ - -E MailInfo *MailBegin(User *u, NickCore *nc, char *subject, char *service); -E MailInfo *MailRegBegin(User *u, NickRequest *nr, char *subject, char *service); -E MailInfo *MailMemoBegin(NickCore * nc); -E void MailEnd(MailInfo *mail); -E void MailReset(User *u, NickCore *nc); -E int MailValidate(const char *email); - /**** main.c ****/ E const char version_number[]; E const char version_number_dotted[]; E const char version_build[]; E char *version_protocol; -E const char version_flags[]; E std::string services_dir; E std::string log_filename; @@ -267,7 +253,8 @@ E char *sstrdup(const char *s); /**** memoserv.c ****/ E void ms_init(); -E void memoserv(User * u, char *buf); +E void memoserv(User * u, const std::string &buf); +E void rsend_notify(User *u, Memo *m, const char *chan); E void check_memos(User * u); E MemoInfo *getmemoinfo(const char *name, int *ischan, int *isforbid); E void memo_send(User * u, const char *name, const char *text, int z); @@ -279,7 +266,7 @@ E int m_nickcoll(const char *user); E int m_away(const char *source, const char *msg); E int m_kill(const std::string &nick, const char *msg); E int m_motd(const char *source); -E int m_privmsg(const char *source, const std::string &receiver, const char *msg); +E int m_privmsg(const std::string &source, const std::string &receiver, const std::string &message); E int m_stats(const char *source, int ac, const char **av); E int m_whois(const char *source, const char *who); E int m_time(const char *source, int ac, const char **av); @@ -288,6 +275,7 @@ E int m_version(const char *source, int ac, const char **av); /**** misc.c ****/ +E bool IsFile(const std::string &filename); E int toupper(char); E int tolower(char); E char *strscpy(char *d, const char *s, size_t len); @@ -307,10 +295,6 @@ E const char *duration(NickCore *nc, char *buf, int bufsize, time_t seconds); E const char *expire_left(NickCore *nc, char *buf, int len, time_t expires); E int doValidHost(const char *host, int type); -typedef int (*range_callback_t) (User * u, int num, va_list args); -E int process_numlist(const char *numstr, int *count_ret, - range_callback_t callback, User * u, ...); - E int isValidHost(const char *host, int type); E int isvalidchar(const char c); @@ -354,25 +338,18 @@ E int str_is_cidr(char *str, uint32 * ip, uint32 * mask, char **host); /**** modes.cpp ****/ /* Number of generic modes we support */ E unsigned GenericChannelModes, GenericUserModes; -E std::bitset<128> DefMLockOn; -E std::bitset<128> DefMLockOff; +E Flags<ChannelModeName> DefMLockOn; +E Flags<ChannelModeName> DefMLockOff; E std::map<ChannelModeName, std::string> DefMLockParams; /* Modes to set on bots when they join the channel */ E std::list<ChannelModeStatus *> BotModes; E void SetDefaultMLock(); -/**** modules.c ****/ -E void modules_unload_all(bool unload_proto); /* Read warnings near function source */ - /**** nickserv.c ****/ -E NickAlias *nalists[1024]; -E NickCore *nclists[1024]; -E NickRequest *nrlists[1024]; E NickRequest *findrequestnick(const char *nick); -E void insert_requestnick(NickRequest * nr); -E void alpha_insert_alias(NickAlias * na); -E void insert_core(NickCore * nc); +E NickRequest *findrequestnick(const std::string &nick); +E NickRequest *findrequestnick(const ci::string &nick); E void get_aliases_stats(long *nrec, long *memuse); E void get_core_stats(long *nrec, long *memuse); E void change_core_display(NickCore * nc); @@ -380,59 +357,18 @@ E void change_core_display(NickCore * nc, const char *newdisplay); E int do_setmodes(User * u); E void ns_init(); -E void nickserv(User * u, char *buf); +E void nickserv(User * u, const std::string &buf); E int validate_user(User * u); E void expire_nicks(); E void expire_requests(); E NickAlias *findnick(const char *nick); E NickAlias *findnick(const std::string &nick); -E NickCore *findcore(const char *nick); +E NickAlias *findnick(const ci::string &nick); +E NickCore *findcore(const char *nick); +E NickCore *findcore(const std::string &nick); +E NickCore *findcore(const ci::string &nick); E bool is_on_access(User *u, NickCore *nc); -/**** operserv.c ****/ - -E SList akills, sglines, sqlines, szlines; - -E int DefConModesSet; -E Flags<ChannelModeName> DefConModesOn; -E Flags<ChannelModeName> DefConModesOff; -E std::map<ChannelModeName, std::string> DefConModesOnParams; -E bool SetDefConParam(ChannelModeName, std::string &); -E bool GetDefConParam(ChannelModeName, std::string *); -E void UnsetDefConParam(ChannelModeName); - -E void operserv(User *u, char *buf); -E void os_init(); - -E int add_akill(User *u, const char *mask, const char *by, const time_t expires, const char *reason); -E int check_akill(const char *nick, const char *username, const char *host, const char *vhost, const char *ip); -E void expire_akills(); -E void oper_global(char *nick, const char *fmt, ...); - -E int add_sgline(User *u, const char *mask, const char *by, time_t expires, const char *reason); -E int check_sgline(const char *nick, const char *realname); -E void expire_sglines(); - -E int add_sqline(User *u, const char *mask, const char *by, time_t expires, const char *reason); -E int check_sqline(const char *nick, int nick_change); -E void expire_sqlines(); -E int check_chan_sqline(const char *chan); - -E int add_szline(User * u, const char *mask, const char *by, - time_t expires, const char *reason); -E void expire_szlines(); -E int check_szline(const char *nick, char *ip); - -E Server *server_global(Server * s, char *msg); - -E std::vector<NewsItem *> News; - -E bool CheckDefCon(DefconLevel Level); -E bool CheckDefCon(int level, DefconLevel Level); -E void AddDefCon(int level, DefconLevel Level); -E void DelDefCon(int level, DefconLevel Level); -E std::vector<std::bitset<32> > DefCon; - /**** process.c ****/ E int allow_ignore; @@ -459,45 +395,11 @@ E void notice_lang(const std::string &source, User *dest, int message, ...); // E void notice_help(const char *source, User *dest, int message, ...); // MARK_DEPRECATED; -/**** servers.c ****/ - -E Server *servlist; -E Server *me_server; -E Server *serv_uplink; -E Flags<CapabType> Capab; -E CapabInfo Capab_Info[]; - -E Server *first_server(ServerFlag flag); -E Server *next_server(ServerFlag flag); - -E void CapabParse(int ac, const char **av); -E int is_ulined(const char *server); -E int is_sync(Server *server); - -E Server *new_server(Server * uplink, const char *name, const char *desc, ServerFlag flag, const std::string &suid); - -E Server *findserver(Server *s, const char *name); - -E void do_server(const char *source, const char *servername, const char *hops, const char *descript, const std::string &numeric); -E void do_squit(const char *source, int ac, const char **av); -E int anope_check_sync(const char *name); - -E void finish_sync(Server *serv, int sync_links); - -E void ts6_uid_init(); -E void ts6_uid_increment(unsigned int slot); -E const char *ts6_uid_retrieve(); - -E const char *ts6_sid_retrieve(); - /**** sessions.c ****/ E Exception *exceptions; E int16 nexceptions; -E Session *sessionlist[1024]; -E int32 nsessions; - E void get_session_stats(long *nrec, long *memuse); E void get_exception_stats(long *nrec, long *memuse); @@ -506,7 +408,7 @@ E void del_session(const char *host); E void expire_exceptions(); -E Session *findsession(const char *host); +E Session *findsession(const std::string &host); E Exception *find_host_exception(const char *host); E Exception *find_hostip_exception(const char *host, const char *hostip); @@ -514,19 +416,6 @@ E int exception_add(User * u, const char *mask, const int limit, const char *reason, const char *who, const time_t expires); -/**** slist.c ****/ -E int slist_add(SList *slist, void *item); -E void slist_clear(SList *slist, int free); -E int slist_delete(SList *slist, int index); -E int slist_delete_range(SList *slist, const char *range, slist_delcheckcb_t cb, ...); -E int slist_enum(SList *slist, const char *range, slist_enumcb_t cb, ...); -E int slist_full(SList *slist); -E int slist_indexof(SList *slist, void *item); -E void slist_init(SList *slist); -E void slist_pack(SList *slist); -E int slist_remove(SList *slist, void *item); -E int slist_setcapacity(SList *slist, int16 capacity); - /**** sockets.cpp ****/ E SocketEngine socketEngine; E int32 TotalRead; @@ -534,23 +423,18 @@ E int32 TotalWritten; /**** users.c ****/ -E User *userlist[1024]; - E int32 opcnt; E uint32 maxusercnt, usercnt; E time_t maxusertime; E void get_user_stats(long *nusers, long *memuse); + +E User *finduser(const char *nick); E User *finduser(const std::string &nick); -E User *firstuser(); -E User *nextuser(); +E User *finduser(const ci::string &nick); -E User *find_byuid(const std::string &uid); -E User *first_uid(); -E User *next_uid(); E Server *findserver_uid(Server * s, const char *name); E char *TS6SID; -E char *TS6UPLINK; E User *do_nick(const char *source, const char *nick, const char *username, const char *host, const char *server, const char *realname, time_t ts, uint32 ip, const char *vhost, const char *uid); @@ -560,7 +444,6 @@ E void do_quit(const char *source, int ac, const char **av); E void do_kill(const std::string &source, const std::string &reason); E int is_oper(User * user); -E int is_protected(User * user); E int is_excepted(ChannelInfo * ci, User * user); E int is_excepted_mask(ChannelInfo * ci, const char *mask); diff --git a/include/hashcomp.h b/include/hashcomp.h index becebb48e..6d4530dc6 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -15,6 +15,24 @@ #include <string> +#ifndef _WIN32 +// #ifdef HASHMAP_DEPRECATED /* If gcc ver > 4.3 */ + #if 1 + /* GCC4.3+ has deprecated hash_map and uses tr1. But of course, uses a different include to MSVC. */ + #include <tr1/unordered_map> + #define unordered_map_namespace std::tr1 + #else + #include <ext/hash_map> + /* Oddball linux namespace for hash_map */ + #define unordered_map_namespace __gnu_cxx + #define unordered_map hash_map + #endif +#else + /* MSVC 2010+ has tr1. Though MSVC and GCC use different includes! */ + #include <unordered_map> + #define unordered_map_namespace std::tr1 +#endif + /******************************************************* * This file contains classes and templates that deal * with the comparison and hashing of 'irc strings'. @@ -30,9 +48,6 @@ * aware of irc::string. *******************************************************/ -#ifndef LOWERMAP -#define LOWERMAP - /** A mapping of uppercase to lowercase, including scandinavian * 'oddities' as specified by RFC1459, e.g. { -> [, and | -> \ */ @@ -72,8 +87,6 @@ unsigned const char ascii_case_insensitive_map[256] = { 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 /* 240-255 */ }; -#endif - /** The irc namespace contains a number of helper classes. */ namespace irc @@ -470,4 +483,40 @@ class spacesepstream : public sepstream spacesepstream(const char *source) : sepstream(source, ' ') { } }; +/** Class used to hash a std::string, given as the third argument to the unordered_map template + */ +class CoreExport hash_compare_std_string +{ + public: + /** Return a hash value for a string + * @param s The string + * @return The hash value + */ + size_t operator()(const std::string &s) const; +}; + +/** Class used to hash a ci::string, given as the third argument to the unordered_map template + */ +class CoreExport hash_compare_ci_string +{ + public: + /** Return a hash value for a string using case insensitivity + * @param s The string + * @return The hash value + */ + size_t operator()(const ci::string &s) const; +}; + +/** Class used to hash a irc::string, given as the third argument to the unordered_map template + */ +class CoreExport hash_compare_irc_string +{ + public: + /** Return a hash value for a string using RFC1459 case sensitivity rules + * @param s The stirng + * @return The hash value + */ + size_t operator()(const irc::string &s) const; +}; + #endif diff --git a/include/mail.h b/include/mail.h new file mode 100644 index 000000000..5fe25ab08 --- /dev/null +++ b/include/mail.h @@ -0,0 +1,24 @@ + +extern CoreExport bool Mail(User *u, NickRequest *nr, const std::string &service, const std::string &subject, const std::string &message); +extern CoreExport bool Mail(User *u, NickCore *nc, const std::string &service, const std::string &subject, const std::string &message); +extern CoreExport bool Mail(NickCore *nc, const std::string &subject, const std::string &message); +extern CoreExport bool MailValidate(const std::string &email); + +class MailThread : public Thread +{ + private: + std::string MailTo; + std::string Addr; + std::string Subject; + std::string Message; + + bool Success; + public: + MailThread(const std::string &mailto, const std::string &addr, const std::string &subject, const std::string &message) : Thread(), MailTo(mailto), Addr(addr), Subject(subject), Message(message), Success(false) + { + } + + ~MailThread(); + + void Run(); +}; diff --git a/include/messages.h b/include/messages.h deleted file mode 100644 index a5505471e..000000000 --- a/include/messages.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Declarations of IRC message structures, variables, and functions. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -/*************************************************************************/ -#include "modules.h" - -extern Message messages[]; -extern void moduleAddMsgs(); -extern Message *find_message(const char *name); - - -/*************************************************************************/ diff --git a/include/modes.h b/include/modes.h index 452dbfdd1..d1b601b31 100644 --- a/include/modes.h +++ b/include/modes.h @@ -76,9 +76,11 @@ enum ModeClass */ class CoreExport Mode { - public: + public: /* Class of mode this is */ ModeClass Class; + /* The mode name, as a string */ + std::string NameAsString; /* Mode char for this */ char ModeChar; /* Type of mode this is */ @@ -86,10 +88,11 @@ class CoreExport Mode /** Default constructor * @param mClass The type of mode this is + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param type The mode type */ - Mode(ModeClass mClass, char modeChar, ModeType type); + Mode(ModeClass mClass, const std::string &mNameAsString, char modeChar, ModeType type); /** Default destructor */ @@ -100,30 +103,31 @@ class CoreExport Mode */ class CoreExport UserMode : public Mode { - public: - + public: /* Mode name */ UserModeName Name; /** Default constructor * @param nName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ - UserMode(UserModeName mName, char modeChar); + UserMode(UserModeName mName, const std::string &mNameAsString, char modeChar); /** Default destructor */ virtual ~UserMode(); }; -class UserModeParam : public UserMode +class CoreExport UserModeParam : public UserMode { public: /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ - UserModeParam(UserModeName mName, char modeChar); + UserModeParam(UserModeName mName, const std::string &mNameAsString, char modeChar); /** Check if the param is valid * @param value The param @@ -136,16 +140,16 @@ class UserModeParam : public UserMode */ class CoreExport ChannelMode : public Mode { - public: - + public: /* Mode name */ ChannelModeName Name; /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ - ChannelMode(ChannelModeName mName, char modeChar); + ChannelMode(ChannelModeName mName, const std::string &mNameAsString, char modeChar); /** Default destructor */ @@ -163,13 +167,13 @@ class CoreExport ChannelMode : public Mode */ class CoreExport ChannelModeList : public ChannelMode { - public: - + public: /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ - ChannelModeList(ChannelModeName mName, char modeChar); + ChannelModeList(ChannelModeName mName, const std::string &mNameAsString, char modeChar); /** Default destructor */ @@ -199,14 +203,14 @@ class CoreExport ChannelModeList : public ChannelMode */ class CoreExport ChannelModeParam : public ChannelMode { - public: - + public: /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param MinusArg true if this mode sends no arg when unsetting */ - ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg = false); + ChannelModeParam(ChannelModeName mName, const std::string &mNameAsString, char modeChar, bool MinusArg = false); /** Default destructor */ @@ -226,16 +230,17 @@ class CoreExport ChannelModeParam : public ChannelMode */ class CoreExport ChannelModeStatus : public ChannelMode { - public: + public: /* The symbol, eg @ % + */ char Symbol; /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param mSymbol The symbol for the mode, eg @ % + */ - ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol); + ChannelModeStatus(ChannelModeName mName, const std::string &mNameAsString, char modeChar, char mSymbol); /** Default destructor */ @@ -246,8 +251,8 @@ class CoreExport ChannelModeStatus : public ChannelMode */ class CoreExport ChannelModeBan : public ChannelModeList { - public: - ChannelModeBan(char modeChar) : ChannelModeList(CMODE_BAN, modeChar) { } + public: + ChannelModeBan(char modeChar) : ChannelModeList(CMODE_BAN, "CMODE_BAN", modeChar) { } void AddMask(Channel *chan, const char *mask); @@ -258,8 +263,8 @@ class CoreExport ChannelModeBan : public ChannelModeList */ class CoreExport ChannelModeExcept : public ChannelModeList { - public: - ChannelModeExcept(char modeChar) : ChannelModeList(CMODE_EXCEPT, modeChar) { } + public: + ChannelModeExcept(char modeChar) : ChannelModeList(CMODE_EXCEPT, "CMODE_EXCEPT", modeChar) { } void AddMask(Channel *chan, const char *mask); @@ -270,8 +275,8 @@ class CoreExport ChannelModeExcept : public ChannelModeList */ class CoreExport ChannelModeInvite : public ChannelModeList { - public: - ChannelModeInvite(char modeChar) : ChannelModeList(CMODE_INVITEOVERRIDE, modeChar) { } + public: + ChannelModeInvite(char modeChar) : ChannelModeList(CMODE_INVITEOVERRIDE, "CMODE_INVITEOVERRIDE", modeChar) { } void AddMask(Channel *chan, const char *mask); @@ -283,8 +288,8 @@ class CoreExport ChannelModeInvite : public ChannelModeList */ class CoreExport ChannelModeKey : public ChannelModeParam { - public: - ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, modeChar) { } + public: + ChannelModeKey(char modeChar) : ChannelModeParam(CMODE_KEY, "CMODE_KEY", modeChar) { } bool IsValid(const std::string &value); }; @@ -293,8 +298,8 @@ class CoreExport ChannelModeKey : public ChannelModeParam */ class ChannelModeFlood : public ChannelModeParam { - public: - ChannelModeFlood(char modeChar, bool minusNoArg = false) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + public: + ChannelModeFlood(char modeChar, bool minusNoArg = false) : ChannelModeParam(CMODE_FLOOD, "CMODE_FLOOD", modeChar, minusNoArg) { } bool IsValid(const std::string &value); }; @@ -304,8 +309,8 @@ class ChannelModeFlood : public ChannelModeParam */ class CoreExport ChannelModeAdmin : public ChannelMode { - public: - ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, modeChar) { } + public: + ChannelModeAdmin(char modeChar) : ChannelMode(CMODE_ADMINONLY, "CMODE_ADMINONLY", modeChar) { } /* Opers only */ bool CanSet(User *u); @@ -316,8 +321,8 @@ class CoreExport ChannelModeAdmin : public ChannelMode */ class CoreExport ChannelModeOper : public ChannelMode { - public: - ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, modeChar) { } + public: + ChannelModeOper(char modeChar) : ChannelMode(CMODE_OPERONLY, "CMODE_OPERONLY", modeChar) { } /* Opers only */ bool CanSet(User *u); @@ -328,8 +333,8 @@ class CoreExport ChannelModeOper : public ChannelMode */ class CoreExport ChannelModeRegistered : public ChannelMode { - public: - ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, modeChar) { } + public: + ChannelModeRegistered(char modeChar) : ChannelMode(CMODE_REGISTERED, "CMODE_REGISTERED", modeChar) { } /* No one mlocks +r */ bool CanSet(User *u); @@ -369,7 +374,7 @@ class StackerInfo */ class CoreExport ModeManager { - protected: + protected: /* List of pairs of user/channels and their stacker info */ static std::list<std::pair<void *, StackerInfo *> > StackerObjects; @@ -413,7 +418,10 @@ class CoreExport ModeManager */ static void StackerAddInternal(BotInfo *bi, void *Object, void *Mode, bool Set, const std::string &Param, StackerType Type); - public: + public: + /* List of all modes Anope knows about */ + static std::list<Mode *> Modes; + /* User modes */ static std::map<char, UserMode *> UserModesByChar; static std::map<UserModeName, UserMode *> UserModesByName; @@ -421,11 +429,8 @@ class CoreExport ModeManager static std::map<char, ChannelMode *> ChannelModesByChar; static std::map<ChannelModeName, ChannelMode *> ChannelModesByName; /* Although there are two different maps for UserModes and ChannelModes - * the pointers in each are the same. This is used to increase - * efficiency. - */ - /* List of all modes Anope knows about */ - static std::list<Mode *> Modes; + * the pointers in each are the same. This is used to increase efficiency. + */ /** Add a user mode to Anope * @param um A UserMode or UserMode derived class diff --git a/include/modules.h b/include/modules.h index bd553c2cc..8e6711b3b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -19,13 +19,13 @@ #include "timers.h" #include "hashcomp.h" #include "version.h" +#include "commands.h" /* Cross OS compatibility macros */ #ifdef _WIN32 typedef HMODULE ano_module_t; #define dlopen(file, unused) LoadLibrary(file) - E const char *dlerror(); #define dlsym(file, symbol) (HMODULE)GetProcAddress(file, symbol) #define dlclose(file) FreeLibrary(file) ? 0 : 1 #define ano_modclearerr() SetLastError(0) @@ -104,68 +104,6 @@ do { \ } \ } while(0); - - -/** Priority types which can be returned from Module::Prioritize() - */ -enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }; - - - -/*************************************************************************/ -#define CMD_HASH(x) (((x)[0]&31)<<5 | ((x)[1]&31)) /* Will gen a hash from a string :) */ -#define MAX_CMD_HASH 1024 - -/** The return value from commands. - */ -enum CommandReturn -{ - MOD_CONT, - MOD_STOP -}; - -#define HOSTSERV HS_cmdTable /* using HOSTSERV etc. looks nicer than HS_cmdTable for modules */ -#define BOTSERV BS_cmdTable -#define MEMOSERV MS_cmdTable -#define NICKSERV NS_cmdTable -#define CHANSERV CS_cmdTable -#define OPERSERV OS_cmdTable -#define IRCD IRCD_cmdTable -#define MODULE_HASH Module_table -#define EVENT EVENT_cmdTable -#define EVENTHOOKS HOOK_cmdTable - -/********************************************************************** - * Module Returns - **********************************************************************/ -#define MOD_ERR_OK 0 -#define MOD_ERR_MEMORY 1 -#define MOD_ERR_PARAMS 2 -#define MOD_ERR_EXISTS 3 -#define MOD_ERR_NOEXIST 4 -#define MOD_ERR_NOUSER 5 -#define MOD_ERR_NOLOAD 6 -#define MOD_ERR_NOUNLOAD 7 -#define MOD_ERR_SYNTAX 8 -#define MOD_ERR_NODELETE 9 -#define MOD_ERR_UNKNOWN 10 -#define MOD_ERR_FILE_IO 11 -#define MOD_ERR_NOSERVICE 12 -#define MOD_ERR_NO_MOD_NAME 13 - -/*************************************************************************/ -/* Macros to export the Module API functions/variables */ -#ifndef _WIN32 -#define MDE -#else -#ifndef MODULE_COMPILE -#define MDE __declspec(dllexport) -#else -#define MDE __declspec(dllimport) -#endif -#endif -/*************************************************************************/ - #if !defined(_WIN32) #include <dlfcn.h> /* Define these for systems without them */ @@ -185,95 +123,42 @@ enum CommandReturn const char *ano_moderr(); #endif -typedef enum { CORE,PROTOCOL,THIRD,SUPPORTED,QATESTED,ENCRYPTION,DATABASE } MODType; -typedef enum { MOD_OP_LOAD, MOD_OP_UNLOAD } ModuleOperation; - -/*************************************************************************/ -/* Structure for information about a *Serv command. */ - -struct CommandHash; -typedef struct ModuleLang_ ModuleLang; -typedef struct ModuleHash_ ModuleHash; -typedef struct Message_ Message; -typedef struct MessageHash_ MessageHash; - -/*************************************************************************/ - - - - -extern MDE CommandHash *HOSTSERV[MAX_CMD_HASH]; -extern MDE CommandHash *BOTSERV[MAX_CMD_HASH]; -extern MDE CommandHash *MEMOSERV[MAX_CMD_HASH]; -extern MDE CommandHash *NICKSERV[MAX_CMD_HASH]; -extern MDE CommandHash *CHANSERV[MAX_CMD_HASH]; -extern MDE CommandHash *OPERSERV[MAX_CMD_HASH]; -extern MDE MessageHash *IRCD[MAX_CMD_HASH]; -extern MDE ModuleHash *MODULE_HASH[MAX_CMD_HASH]; +extern CoreExport Module *FindModule(const std::string &name); +int protocol_module_init(); +extern CoreExport Message *createMessage(const char *name, int (*func)(const char *source, int ac, const char **av)); +std::vector<Message *> FindMessage(const std::string &name); +extern CoreExport bool moduleMinVersion(int major,int minor,int patch,int build); -struct ModuleLang_ { - int argc; - char **argv; -}; - -enum CommandFlag +enum ModuleReturn { - CFLAG_ALLOW_UNREGISTERED, - CFLAG_ALLOW_FORBIDDEN, - CFLAG_ALLOW_SUSPENDED, - CFLAG_ALLOW_UNREGISTEREDCHANNEL, - CFLAG_STRIP_CHANNEL, - CFLAG_DISABLE_FANTASY + MOD_ERR_OK, + MOD_ERR_MEMORY, + MOD_ERR_PARAMS, + MOD_ERR_EXISTS, + MOD_ERR_NOEXIST, + MOD_ERR_NOUSER, + MOD_ERR_NOLOAD, + MOD_ERR_NOUNLOAD, + MOD_ERR_SYNTAX, + MOD_ERR_NODELETE, + MOD_ERR_UNKNOWN, + MOD_ERR_FILE_IO, + MOD_ERR_NOSERVICE, + MOD_ERR_NO_MOD_NAME }; -/** Every services command is a class, inheriting from Command. +/** Priority types which can be returned from Module::Prioritize() */ -class CoreExport Command : public Flags<CommandFlag> -{ - public: - size_t MaxParams; - size_t MinParams; - std::string name; - std::string permission; - - /** Create a new command. - * @param min_params The minimum number of parameters the parser will require to execute this command - * @param max_params The maximum number of parameters the parser will create, after max_params, all will be combined into the last argument. - * NOTE: If max_params is not set (default), there is no limit to the max number of params. - */ - Command(const std::string &sname, size_t min_params, size_t max_params = 0, const std::string &spermission = ""); - - virtual ~Command(); - - /** Execute this command. - * @param u The user executing the command. - */ - virtual CommandReturn Execute(User *u, const std::vector<ci::string> &); - - /** Requested when the user is requesting help on this command. Help on this command should be sent to the user. - * @param u The user requesting help - * @param subcommand The subcommand the user is requesting help on, or an empty string. (e.g. /ns help set foo bar lol gives a subcommand of "FOO BAR LOL") - * @return true if help was provided to the user, false otherwise. - */ - virtual bool OnHelp(User *u, const ci::string &subcommand); - - /** Requested when the user provides bad syntax to this command (not enough params, etc). - * @param u The user executing the command. - * @param subcommand The subcommand the user tried to use - */ - virtual void OnSyntaxError(User *u, const ci::string &subcommand); +enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER }; +enum MODType { CORE, PROTOCOL, THIRD, SUPPORTED, QATESTED, ENCRYPTION, DATABASE }; - /** Set which command permission (e.g. chanserv/forbid) is required for this command. - * @param reststr The permission required to successfully execute this command - */ - void SetPermission(const std::string &reststr); +struct Message; +extern CoreExport std::multimap<std::string, Message *> MessageMap; +class Module; +extern CoreExport std::deque<Module *> Modules; - /* Module related stuff */ - int core; /* Can this command be deleted? */ - char *mod_name; /* Name of the module who owns us, NULL for core's */ - char *service; /* Service we provide this command for */ - Command *next; -}; +/*************************************************************************/ +/* Structure for information about a *Serv command. */ class Version { @@ -332,15 +217,31 @@ class CoreExport Module */ std::list<CallBack *> CallBacks; + /** Handle for this module, obtained from dlopen() + */ ano_module_t handle; + + /** Time this module was created + */ time_t created; + + /** Version of this module + */ std::string version; + + /** Author of the module + */ std::string author; + /** What type this module is + */ MODType type; - MessageHash *msgList[MAX_CMD_HASH]; - ModuleLang lang[NUM_LANGS]; + struct ModuleLang + { + int argc; + char **argv; + } lang[NUM_LANGS]; /** Creates and initialises a new module. * @param loadernick The nickname of the user loading the module. @@ -384,7 +285,7 @@ class CoreExport Module * compiled against * @return The version */ - virtual Version GetVersion() { return Version(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); } + Version GetVersion() { return Version(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD); } /** * Allow a module to add a set of language strings to anope @@ -419,50 +320,19 @@ class CoreExport Module /** * Add a module provided command to the given service. - * e.g. AddCommand(NICKSERV,c,MOD_HEAD); - * @param cmdTable the services to add the command to - * @param c the command to add + * @param bi The service to add the command to + * @param c The command to add * @return MOD_ERR_OK on successfully adding the command */ - int AddCommand(CommandHash *cmdTable[], Command * c); + int AddCommand(BotInfo *bi, Command *c); /** * Delete a command from the service given. - * @param cmdTable the cmdTable for the services to remove the command from - * @param name the name of the command to delete from the service + * @param bi The service to remove the command from + * @param c Thec command to delete * @return returns MOD_ERR_OK on success */ - int DelCommand(CommandHash * cmdTable[], const char *name); - - /** Called on NickServ HELP - * @param u The user requesting help - */ - virtual void OnNickServHelp(User *u) { } - - /** Called on ChanServ HELP - * @param u The user requesting help - */ - virtual void OnChanServHelp(User *u) { } - - /** Called on Botserv HELP - * @param u The user requesting help - */ - virtual void OnBotServHelp(User *u) { } - - /** Called on HostServ HELP - * @param u The user requesting help - */ - virtual void OnHostServHelp(User *u) { } - - /** Called on OperServ HELP - * @param u The user requesting help - */ - virtual void OnOperServHelp(User *u) { } - - /** Called on MemoServ HELP - * @param u The user requesting help - */ - virtual void OnMemoServHelp(User *u) { } + int DelCommand(BotInfo *bi, Command *c); /** Called when the ircd notifies that a user has been kicked from a channel. * @param c The channel the user has been kicked from. @@ -519,13 +389,14 @@ class CoreExport Module virtual void OnUserNickChange(User *u, const std::string &oldnick) { } /** Called immediatly when a user tries to run a command - * @param service The service * @param u The user - * @param cmd The command + * @param bi The bot the command is being run from + * @param command The command + * @param message The parameters used for the command * @param c The command class (if it exists) * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it */ - virtual EventReturn OnPreCommandRun(const std::string &service, User *u, const char *cmd, Command *c) { return EVENT_CONTINUE; } + virtual EventReturn OnPreCommandRun(User *u, BotInfo *bi, const ci::string &command, const ci::string &message, Command *c) { return EVENT_CONTINUE; } /** Called before a command is due to be executed. * @param u The user executing the command @@ -534,7 +405,7 @@ class CoreExport Module * @param params The parameters the user is sending * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it */ - virtual EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) { return EVENT_CONTINUE; } + virtual EventReturn OnPreCommand(User *u, BotInfo *service, const ci::string &command, const std::vector<ci::string> ¶ms) { return EVENT_CONTINUE; } /** Called after a command has been executed. * @param u The user executing the command @@ -542,7 +413,7 @@ class CoreExport Module * @param command The command the user executed * @param params The parameters the user sent */ - virtual void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) { } + virtual void OnPostCommand(User *u, BotInfo *service, const ci::string &command, const std::vector<ci::string> ¶ms) { } /** Called after the core has finished loading the databases, but before * we connect to the server @@ -573,7 +444,7 @@ class CoreExport Module * @param ci The channel it's being used in * @param params The params */ - virtual void OnBotFantasy(char *command, User *u, ChannelInfo *ci, char *params) { } + virtual void OnBotFantasy(const std::string &command, User *u, ChannelInfo *ci, const std::string ¶ms) { } /** Called on fantasy command without access * @param command The command @@ -581,7 +452,7 @@ class CoreExport Module * @param ci The channel it's being used in * @param params The params */ - virtual void OnBotNoFantasyAccess(const char *command, User *u, ChannelInfo *ci, const char *params) { } + virtual void OnBotNoFantasyAccess(const std::string &command, User *u, ChannelInfo *ci, const std::string ¶ms) { } /** Called after a bot joins a channel * @param ci The channael @@ -661,17 +532,20 @@ class CoreExport Module */ virtual void OnChanExpire(const char *chname) { } - /** Called before anope connects to its uplink + /** Called before Anope connects to its uplink + * @param u The uplink we're going to connect to + * @param Number What number the uplink is + * @return Other than EVENT_CONTINUE to stop attempting to connect */ - virtual void OnPreServerConnect() { } + virtual EventReturn OnPreServerConnect(Uplink *u, int Number) { return EVENT_CONTINUE; } /** Called when Anope connects to its uplink */ virtual void OnServerConnect() { } - /** Called when we are done synching with the uplink, just before we send the EOB + /** Called when we are almost done synching with the uplink, just before we send the EOB */ - virtual void OnFinishSync(Server *serv) { } + virtual void OnPreUplinkSync(Server *serv) { } /** Called when Anope disconnects from its uplink, before it tries to reconnect */ @@ -714,6 +588,14 @@ class CoreExport Module */ virtual EventReturn OnDatabaseReadMetadata(NickAlias *na, const std::string &key, const std::vector<std::string> ¶ms) { return EVENT_CONTINUE; } + /** Called when nickrequest metadata is read from the database + * @param nr The nickrequest + * @parm key The metadata key + * @param params The params from the database + * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing + */ + virtual EventReturn OnDatabaseReadMetadata(NickRequest *nr, const std::string &key, const std::vector<std::string> ¶ms) { return EVENT_CONTINUE; } + /** Called when botinfo metadata is read from the database * @param bi The botinfo * @param key The metadata key @@ -742,6 +624,12 @@ class CoreExport Module */ virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), NickAlias *na) { } + /** Called when we are wrting metadata for a nickrequest + * @param WriteMetata A callback function used to insert the metadata + * @param nr The nick request + */ + virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), NickRequest *nr) { } + /** Called when we are writing metadata for a botinfo * @param WriteMetata A callback function used to insert the metadata * @param bi The botinfo @@ -782,9 +670,9 @@ class CoreExport Module virtual EventReturn OnPreNickExpire(NickAlias *na) { return EVENT_CONTINUE; } /** Called when a nick drops - * @param nick The nick + * @param na The nick */ - virtual void OnNickExpire(const char *nick) { } + virtual void OnNickExpire(NickAlias *na) { } /** Called when defcon level changes * @param level The level @@ -796,13 +684,13 @@ class CoreExport Module * @param ak The akill * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it */ - virtual EventReturn OnAddAkill(User *u, Akill *ak) { return EVENT_CONTINUE; } + virtual EventReturn OnAddAkill(User *u, XLine *ak) { return EVENT_CONTINUE; } /** Called before an akill is deleted * @param u The user removing the akill * @param ak The akill, can be NULL for all akills! */ - virtual void OnDelAkill(User *u, Akill *ak) { } + virtual void OnDelAkill(User *u, XLine *ak) { } /** Called after an exception has been added * @param u The user who added it @@ -817,20 +705,20 @@ class CoreExport Module */ virtual void OnExceptionDel(User *u, Exception *ex) { } - /** Called before a SXLine is added - * @param u The user adding the SXLine - * @param sx The SXLine - * @param Type The type of SXLine this is + /** Called before a XLine is added + * @param u The user adding the XLine + * @param sx The XLine + * @param Type The type of XLine this is * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it */ - virtual EventReturn OnAddSXLine(User *u, SXLine *sx, SXLineType Type) { return EVENT_CONTINUE; } + virtual EventReturn OnAddXLine(User *u, XLine *x, XLineType Type) { return EVENT_CONTINUE; } - /** Called before a SXLine is deleted - * @param u The user deleting the SXLine - * @param sx The SXLine, can be NULL for all SXLines - * @param Type The type of SXLine this is + /** Called before a XLine is deleted + * @param u The user deleting the XLine + * @param sx The XLine, can be NULL for all XLines + * @param Type The type of XLine this is */ - virtual void OnDelSXLine(User *u, SXLine *sx, SXLineType Type) { } + virtual void OnDelXLine(User *u, XLine *x, XLineType Type) { } /** Called when a server quits * @param server The server @@ -873,18 +761,18 @@ class CoreExport Module /** Called when access is changed * @param ci The channel * @param u The user who changed the access - * @param na The nick whos access was changed + * @param nc The nick whos access was changed * @param level The level of the new access */ - virtual void OnAccessChange(ChannelInfo *ci, User *u, NickAlias *na, int level) { } + virtual void OnAccessChange(ChannelInfo *ci, User *u, NickCore *nc, int level) { } /** Called when access is added * @param ci The channel * @param u The user who added the access - * @para na The nick who was added to access + * @para nc The nick who was added to access * @param level The level they were added at */ - virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickAlias *na, int level) { } + virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level) { } /** Called when the access list is cleared * @param ci The channel @@ -941,16 +829,25 @@ class CoreExport Module virtual void OnChannelDelete(Channel *c) { } /** Called after adding an akick to a channel + * @param u The user adding the akick * @param ci The channel * @param ak The akick */ - virtual void OnAkickAdd(ChannelInfo *ci, AutoKick *ak) { } + virtual void OnAkickAdd(User *u, ChannelInfo *ci, AutoKick *ak) { } /** Called before removing an akick from a channel + * @param u The user removing the akick * @param ci The channel * @param ak The akick */ - virtual void OnAkickDel(ChannelInfo *ci, AutoKick *ak) { } + virtual void OnAkickDel(User *u, ChannelInfo *ci, AutoKick *ak) { } + + /** Called when a user requests info for a channel + * @param u The user requesting info + * @param ci The channel the user is requesting info for + * @param ShowHidden true if we should show the user everything + */ + virtual void OnChanInfo(User *u, ChannelInfo *ci, bool ShowHidden) { } /** Called when a nick is dropped * @param nick The nick @@ -1030,13 +927,20 @@ class CoreExport Module */ virtual void OnNickAddAccess(NickCore *nc, const std::string &entry) { } - /** called from NickCore::EraseAccess() + /** Called from NickCore::EraseAccess() * @param nc pointer to the NickCore * @param entry The access mask */ virtual void OnNickEraseAccess(NickCore *nc, const std::string &entry) { } - /** called when a vhost is deleted + /** Called when a user requests info for a nick + * @param u The user requesting info + * @param na The nick the user is requesting info from + * @param ShowHidden true if we should show the user everything + */ + virtual void OnNickInfo(User *u, NickAlias *na, bool ShowHidden) { } + + /** Called when a vhost is deleted * @param na The nickalias of the vhost */ virtual void OnDeleteVhost(NickAlias *na) { } @@ -1144,8 +1048,9 @@ class CoreExport Module virtual void OnServerSync(Server *s) { } /** Called when we sync with our uplink + * @param s Our uplink */ - virtual void OnUplinkSync() { } + virtual void OnUplinkSync(Server *s) { } }; @@ -1156,33 +1061,35 @@ enum Implementation { I_BEGIN, /* NickServ */ - I_OnNickServHelp, I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop, + I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop, I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnDelNickRequest, I_OnMakeNickRequest, I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess, + I_OnNickInfo, /* ChanServ */ - I_OnChanServHelp, I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange, + I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd, I_OnAccessChange, I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnDelChan, I_OnChannelCreate, I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, + I_OnChanInfo, /* BotServ */ - I_OnBotServHelp, I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign, + I_OnBotJoin, I_OnBotKick, I_OnBotCreate, I_OnBotChange, I_OnBotDelete, I_OnBotAssign, I_OnBotUnAssign, I_OnUserKicked, I_OnBotFantasy, I_OnBotNoFantasyAccess, I_OnBotBan, I_OnBadWordAdd, I_OnBadWordDel, /* HostServ */ - I_OnHostServHelp, I_OnSetVhost, I_OnDeleteVhost, + I_OnSetVhost, I_OnDeleteVhost, /* MemoServ */ - I_OnMemoServHelp, I_OnMemoSend, I_OnMemoDel, + I_OnMemoSend, I_OnMemoDel, /* Users */ I_OnPreUserConnect, I_OnUserConnect, I_OnUserNickChange, I_OnUserQuit, I_OnUserLogoff, I_OnPreJoinChannel, I_OnJoinChannel, I_OnPrePartChannel, I_OnPartChannel, /* OperServ */ - I_OnOperServHelp, I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel, - I_OnAddSXLine, I_OnDelSXLine, + I_OnDefconLevel, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel, + I_OnAddXLine, I_OnDelXLine, /* Database */ I_OnPostLoadDatabases, I_OnSaveDatabase, I_OnLoadDatabase, @@ -1193,7 +1100,7 @@ enum Implementation I_OnModuleLoad, I_OnModuleUnload, /* Other */ - I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnFinishSync, I_OnServerDisconnect, I_OnPreCommandRun, + I_OnReload, I_OnPreServerConnect, I_OnNewServer, I_OnServerConnect, I_OnPreUplinkSync, I_OnServerDisconnect, I_OnPreCommandRun, I_OnPreCommand, I_OnPostCommand, I_OnPreDatabaseExpire, I_OnPreRestart, I_OnRestart, I_OnPreShutdown, I_OnShutdown, I_OnSignal, I_OnServerQuit, I_OnTopicUpdated, I_OnEncrypt, I_OnEncryptInPlace, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword, @@ -1289,7 +1196,13 @@ class CoreExport ModuleManager */ static void ClearCallBacks(Module *m); -private: + /** Unloading all modules, NEVER call this when Anope isn't shutting down. + * Ever. + * @param unload_proto true to unload the protocol module + */ + static void UnloadAll(bool unload_proto); + + private: /** Call the module_delete function to safely delete the module * @param m the module to delete */ @@ -1318,57 +1231,10 @@ class CallBack : public Timer } }; -struct ModuleHash_ { - char *name; - Module *m; - ModuleHash *next; -}; - -struct CommandHash { - char *name; /* Name of the command */ - Command *c; /* Actual command */ - CommandHash *next; /* Next command */ -}; - -struct Message_ { - char *name; +struct Message +{ + std::string name; int (*func)(const char *source, int ac, const char **av); - int core; - Message *next; -}; - -struct MessageHash_ { - char *name; - Message *m; - MessageHash *next; }; -/*************************************************************************/ -/* Module Managment Functions */ -MDE Module *findModule(const char *name); /* Find a module */ - -int protocol_module_init(); /* Load the IRCD Protocol Module up*/ - -/*************************************************************************/ -/*************************************************************************/ -/* Command Managment Functions */ -MDE Command *findCommand(CommandHash *cmdTable[], const char *name); /* Find a command */ - -/*************************************************************************/ - -/* Message Managment Functions */ -MDE Message *createMessage(const char *name,int (*func)(const char *source, int ac, const char **av)); -Message *findMessage(MessageHash *msgTable[], const char *name); /* Find a Message */ -MDE int addMessage(MessageHash *msgTable[], Message *m, int pos); /* Add a Message to a Message table */ -MDE int addCoreMessage(MessageHash *msgTable[], Message *m); /* Add a Message to a Message table */ -int delMessage(MessageHash *msgTable[], Message *m); /* Del a Message from a msg table */ -int destroyMessage(Message *m); /* destroy a Message*/ - -/*************************************************************************/ - -MDE bool moduleMinVersion(int major,int minor,int patch,int build); /* Checks if the current version of anope is before or after a given verison */ - -/************************************************************************/ - #endif -/* EOF */ diff --git a/include/operserv.h b/include/operserv.h new file mode 100644 index 000000000..c9848779b --- /dev/null +++ b/include/operserv.h @@ -0,0 +1,231 @@ +/* OperServ support + * + * (C) 2008-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * $Id$ + * + */ + +extern CoreExport std::vector<NewsItem *> News; +extern CoreExport std::vector<std::bitset<32> > DefCon; +extern CoreExport bool DefConModesSet; +extern CoreExport Flags<ChannelModeName> DefConModesOn; +extern CoreExport Flags<ChannelModeName> DefConModesOff; +extern CoreExport std::map<ChannelModeName, std::string> DefConModesOnParams; + +class XLineManager; +extern CoreExport XLineManager *SGLine; +extern CoreExport XLineManager *SZLine; +extern CoreExport XLineManager *SQLine; +extern CoreExport XLineManager *SNLine; + +extern CoreExport bool SetDefConParam(ChannelModeName, std::string &); +extern CoreExport bool GetDefConParam(ChannelModeName, std::string &); +extern CoreExport void UnsetDefConParam(ChannelModeName); +extern CoreExport bool CheckDefCon(DefconLevel Level); +extern CoreExport bool CheckDefCon(int level, DefconLevel Level); +extern CoreExport void AddDefCon(int level, DefconLevel Level); +extern CoreExport void DelDefCon(int level, DefconLevel Level); + +extern CoreExport void operserv(User *u, const std::string &message); +extern CoreExport void os_init(); + +extern CoreExport void oper_global(char *nick, const char *fmt, ...); +extern CoreExport void server_global(Server *s, const std::string &message); + +enum XLineType +{ + X_SNLINE, + X_SQLINE, + X_SZLINE +}; + +struct XLine +{ + ci::string Mask; + ci::string By; + time_t Created; + time_t Expires; + std::string Reason; + + XLine(const ci::string &mask, const std::string &reason = ""); + + XLine(const ci::string &mask, const ci::string &by, const time_t expires, const std::string &reason); + + ci::string GetNick() const; + ci::string GetUser() const; + ci::string GetHost() const; +}; + +class CoreExport XLineManager +{ + private: + /* List of XLine managers we check users against in XLineManager::CheckAll */ + static std::list<XLineManager *> XLineManagers; + + protected: + /* List of XLines in this XLineManager */ + std::deque<XLine *> XLines; + public: + /** Constructor + */ + XLineManager(); + + /** Destructor + */ + virtual ~XLineManager(); + + /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll + * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling + * clients and one handing them free olines, you would want the akilling one first. This way if a client + * matches an entry on both of the XLineManagers, they would be akilled. + * @param xlm THe XLineManager + */ + static void RegisterXLineManager(XLineManager *xlm); + + /** Unregister a XLineManager + * @param xlm The XLineManager + */ + static void UnregisterXLineManager(XLineManager *xlm); + + /** Check a user against all known XLineManagers + * Wparam u The user + * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match + */ + static std::pair<XLineManager *, XLine *> CheckAll(User *u); + + /** Get the number of XLines in this XLineManager + * @return The number of XLines + */ + const size_t GetCount() const; + + /** Get the XLine list + * @return The list + */ + const std::deque<XLine *>& GetList() const; + + /** Add an entry to this XLineManager + * @param x The entry + */ + void AddXLine(XLine *x); + + /** Delete an entry from this XLineManager + * @param x The entry + * @return true if the entry was found and deleted, else false + */ + bool DelXLine(XLine *x); + + /** Gets an entry by index + * @param index The index + * @return The XLine, or NULL if the index is out of bounds + */ + XLine *GetEntry(unsigned index) const; + + /** Clear the XLine list + */ + void Clear(); + + /** Add an entry to this XLine Manager + * @param bi The bot error replies should be sent from + * @param u The user adding the XLine + * @param mask The mask of the XLine + * @param expires When this should expire + * @param reaosn The reason + * @return A pointer to the XLine + */ + virtual XLine *Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason); + + /** Delete an XLine, eg, remove it from the IRCd. + * @param x The xline + */ + virtual void Del(XLine *x); + + /** Checks if a mask can/should be added to the XLineManager + * @param mask The mask + * @param expires When the mask would expire + * @return A pair of int and XLine*. + * 1 - Mask already exists + * 2 - Mask already exists, but the expiry time was changed + * 3 - Mask is already covered by another mask + * In each case the XLine it matches/is covered by is returned in XLine* + */ + std::pair<int, XLine *> CanAdd(const ci::string &mask, time_t expires); + + /** Checks if this list has an entry + * @param mask The mask + * @return The XLine the user matches, or NULL + */ + XLine *HasEntry(const ci::string &mask) const; + + /** Check a user against all of the xlines in this XLineManager + * @param u The user + * @return The xline the user marches, if any. Also calls OnMatch() + */ + virtual XLine *Check(User *u); + + /** Called when a user matches a xline in this XLineManager + * @param u The user + * @param x The XLine they match + */ + virtual void OnMatch(User *u, XLine *x); + + /** Called when an XLine expires + * @param x The xline + */ + virtual void OnExpire(XLine *x); +}; + +/* This is for AKILLS */ +class SGLineManager : public XLineManager +{ + public: + XLine *Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason); + + void Del(XLine *x); + + void OnMatch(User *u, XLine *x); + + void OnExpire(XLine *x); +}; + +class SNLineManager : public XLineManager +{ + public: + XLine *Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason); + + void Del(XLine *x); + + void OnMatch(User *u, XLine *x); + + void OnExpire(XLine *x); +}; + +class SQLineManager : public XLineManager +{ + public: + XLine *Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason); + + void Del(XLine *x); + + void OnMatch(User *u, XLine *x); + + void OnExpire(XLine *x); + + static bool Check(Channel *c); +}; + +class SZLineManager : public XLineManager +{ + public: + XLine *Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason); + + void Del(XLine *x); + + void OnMatch(User *u, XLine *x); + + void OnExpire(XLine *x); +}; + diff --git a/include/opertype.h b/include/opertype.h index b7fdc67cb..59c9eea6a 100644 --- a/include/opertype.h +++ b/include/opertype.h @@ -31,6 +31,10 @@ class CoreExport OperType * as we don't invoke it often. */ std::list<std::string> commands; + + /** Set of opertypes we inherit from + */ + std::set<OperType *> inheritances; public: /** Create a new opertype of the given name. * @param nname The opertype name, e.g. "sra". @@ -62,4 +66,9 @@ class CoreExport OperType /** Returns the name of this opertype. */ const ci::string &GetName() const; + + /** Make this opertype inherit commands and privs from another opertype + * @param ot The opertype to inherit from + */ + void Inherits(OperType *ot); }; diff --git a/include/pseudo.h b/include/pseudo.h deleted file mode 100644 index d24c43963..000000000 --- a/include/pseudo.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Include extra includes needed by most/all pseudo-clients. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "commands.h" -#include "language.h" -#include "timers.h" -#include "slist.h" diff --git a/include/regchannel.h b/include/regchannel.h index bd5a50ced..e4e8bfdec 100644 --- a/include/regchannel.h +++ b/include/regchannel.h @@ -8,6 +8,9 @@ * */ +typedef unordered_map_namespace::unordered_map<ci::string, ChannelInfo *, hash_compare_ci_string> registered_channel_map; +extern CoreExport registered_channel_map RegisteredChannelList; + /** Flags used for the ChannelInfo class */ enum ChannelInfoFlag @@ -64,9 +67,9 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag> std::map<ChannelModeName, std::string> Params; /* Map of parameters by mode name for mlock */ std::vector<ChanAccess *> access; /* List of authorized users */ std::vector<AutoKick *> akick; /* List of users to kickban */ - std::vector<BadWord *> badwords; /* List of badwords */ - std::bitset<128> mlock_on; /* Modes mlocked on */ - std::bitset<128> mlock_off; /* Modes mlocked off */ + std::vector<BadWord *> badwords; /* List of badwords */ + Flags<ChannelModeName> mlock_on; /* Modes mlocked on */ + Flags<ChannelModeName> mlock_off; /* Modes mlocked off */ public: /** Default constructor @@ -78,7 +81,6 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag> */ ~ChannelInfo(); - ChannelInfo *next, *prev; std::string name; /* Channel name */ NickCore *founder; NickCore *successor; /* Who gets the channel if the founder @@ -159,12 +161,6 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag> */ void EraseAccess(unsigned index); - /** Cleans the channel access list - * - * Cleans up the access list so it no longer contains entries no longer in use. - */ - void CleanAccess(); - /** Clear the entire channel access list * * Clears the entire access list by deleting every item and then clearing the vector. @@ -201,18 +197,14 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag> const unsigned GetAkickCount() const; /** Erase an entry from the channel akick list - * @param akick The akick + * @param index The index of the akick */ - void EraseAkick(AutoKick *akick); + void EraseAkick(unsigned index); /** Clear the whole akick list */ void ClearAkick(); - /** Clean all of the nonused entries from the akick list - */ - void CleanAkick(); - /** Add a badword to the badword list * @param word The badword * @param type The type (SINGLE START END) @@ -232,17 +224,18 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag> const unsigned GetBadWordCount() const; /** Remove a badword - * @param badword The badword + * @param index The index of the badword */ - void EraseBadWord(BadWord *badword); + void EraseBadWord(unsigned index); /** Clear all badwords from the channel */ void ClearBadWords(); - /** Clean all of the nonused entries from the badwords list + /** Loads MLocked modes from extensible. This is used from database loading because Anope doesn't know what modes exist + * until after it connects to the IRCd. */ - void CleanBadWords(); + void LoadMLock(); /** Check if a mode is mlocked * @param Name The mode diff --git a/include/servers.h b/include/servers.h new file mode 100644 index 000000000..3a26e1546 --- /dev/null +++ b/include/servers.h @@ -0,0 +1,179 @@ +/* Anope */ +extern CoreExport Server *Me; + +extern CoreExport void CapabParse(int ac, const char **av); + +extern CoreExport void do_server(const std::string &source, const std::string &servername, unsigned int hops, const std::string &descript, const std::string &numeric); +extern CoreExport void do_squit(const char *source, int ac, const char **av); + +extern CoreExport const char *ts6_uid_retrieve(); +extern CoreExport const char *ts6_sid_retrieve(); + +/* Types of capab + */ +enum CapabType +{ + CAPAB_BEGIN, + + CAPAB_NOQUIT, + CAPAB_TSMODE, + CAPAB_UNCONNECT, + CAPAB_NICKIP, + CAPAB_NSJOIN, + CAPAB_ZIP, + CAPAB_BURST, + CAPAB_TS3, + CAPAB_TS5, + CAPAB_DKEY, + CAPAB_DOZIP, + CAPAB_DODKEY, + CAPAB_QS, + CAPAB_SCS, + CAPAB_PT4, + CAPAB_UID, + CAPAB_KNOCK, + CAPAB_CLIENT, + CAPAB_IPV6, + CAPAB_SSJ5, + CAPAB_SN2, + CAPAB_VHOST, + CAPAB_TOKEN, + CAPAB_SSJ3, + CAPAB_NICK2, + CAPAB_VL, + CAPAB_TLKEXT, + CAPAB_CHANMODE, + CAPAB_SJB64, + CAPAB_NICKCHARS, + + CAPAB_END +}; + +/* CAPAB stuffs */ +struct CapabInfo +{ + std::string Token; + CapabType Flag; +}; + +extern CoreExport Flags<CapabType> Capab; +extern CoreExport CapabInfo Capab_Info[]; + +/** Flags set on servers + */ +enum ServerFlag +{ + /* Server is syncing */ + SERVER_SYNCING, + /* This server was juped */ + SERVER_JUPED +}; + +/** Class representing a server + */ +class CoreExport Server : public Flags<ServerFlag> +{ + private: + /* Server name */ + std::string Name; + /* Hops between services and server */ + unsigned int Hops; + /* Server description */ + std::string Description; + /* Server ID */ + std::string SID; + /* Links for this server */ + std::list<Server *>* Links; + /* Uplink for this server */ + Server *UplinkServer; + + /* Reason this server was quit */ + std::string QReason; + + public: + /** Constructor + * @param uplink The uplink this server is from, is only NULL when creating Me + * @param name The server name + * @param hops Hops from services server + * @param description Server rdescription + * @param sid Server sid/numeric + */ + Server(Server *uplink, const std::string &name, unsigned int hops, const std::string &description, const std::string &sid); + + /** Destructor + */ + ~Server(); + + /** Delete this server with a reason + * @param reason The reason + */ + void Delete(const std::string &reason); + + /** Get the name for this server + * @return The name + */ + const std::string& GetName() const; + + /** Get the number of hops this server is from services + * @return Number of hops + */ + unsigned int GetHops() const; + + /** Set the server description + * @param desc The new description + */ + void SetDescription(const std::string& desc); + + /** Get the server description + * @return The server description + */ + const std::string& GetDescription() const; + + /** Get the server numeric/SID + * @return The numeric/SID + */ + const std::string& GetSID() const; + + /** Get the list of links this server has, or NULL if it has none + * @return A list of servers + */ + const std::list<Server*>* GetLinks() const; + + /** Get the uplink server for this server, if this is our uplink will be Me + * @return The servers uplink + */ + Server* GetUplink() const; + + /** Adds a link to this server + * @param s The linking server + */ + void AddLink(Server *s); + + /** Delinks a server from this server + * @param s The server + */ + void DelLink(Server *s); + + /** Finish syncing this server and optionally all links to it + * @param SyncLinks True to sync the links for this server too (if any) + */ + void Sync(bool SyncLinks); + + /** Check if this server is synced + * @return true or false + */ + bool IsSynced() const; + + /** Check if this server is ULined + * @return true or false + */ + bool IsULined() const; + + /** Find a server + * @param name The name or SID/numeric + * @param s The server list to search for this server on, defaults to our Uplink + * @return The server + */ + static Server* Find(const std::string &name, Server *s = NULL); +}; + diff --git a/include/services.h b/include/services.h index 2741e0178..4994984e0 100644 --- a/include/services.h +++ b/include/services.h @@ -17,7 +17,8 @@ /*************************************************************************/ #include "sysconf.h" -#include "config.h" + +#define BUFSIZE 1024 /* Some SUN fixs */ #ifdef __sun @@ -33,9 +34,9 @@ # define u_int32_t uint32_t # define u_int64_t uint64_t -# ifndef INADDR_NONE -# define INADDR_NONE (-1) -# endif +# ifndef INADDR_NONE +# define INADDR_NONE (-1) +# endif #endif @@ -51,7 +52,7 @@ #include <sys/stat.h> /* for umask() on some systems */ #include <sys/types.h> - +#include <assert.h> #include <fcntl.h> #ifndef _WIN32 @@ -90,10 +91,18 @@ # define inet_ntop inet_ntop_ # define MARK_DEPRECATED +extern CoreExport const char *dlerror(); extern CoreExport int inet_pton(int af, const char *src, void *dst); extern CoreExport const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif +/* Telling compilers about printf()-like functions: */ +#ifdef __GNUC__ +# define FORMAT(type,fmt,start) __attribute__((format(type,fmt,start))) +#else +# define FORMAT(type,fmt,start) +#endif + #ifdef HAVE_GETTIMEOFDAY # include <sys/time.h> #endif @@ -139,10 +148,6 @@ extern int strncasecmp(const char *, const char *, size_t); #define tolower tolower_ #define toupper toupper_ -/* We also have our own encrypt(). */ -#define encrypt encrypt_ - - #ifdef __WINS__ #ifndef BKCHECK #define BKCHECK @@ -158,12 +163,12 @@ extern int strncasecmp(const char *, const char *, size_t); /** This definition is used as shorthand for the various classes * and functions needed to make a module loadable by the OS. - * It defines the class factory and external init_module function. + * It defines the class factory and external AnopeInit and AnopeFini functions. */ #ifdef _WIN32 #define MODULE_INIT(x) \ - extern "C" DllExport Module *init_module(const std::string &, const std::string &); \ - extern "C" Module *init_module(const std::string &modname, const std::string &creator) \ + extern "C" DllExport Module *AnopeInit(const std::string &, const std::string &); \ + extern "C" Module *AnopeInit(const std::string &modname, const std::string &creator) \ { \ return new x(modname, creator); \ } \ @@ -177,27 +182,26 @@ extern int strncasecmp(const char *, const char *, size_t); } \ return TRUE; \ } \ - extern "C" DllExport void destroy_module(x *); \ - extern "C" void destroy_module(x *m) \ + extern "C" DllExport void AnopeFini(x *); \ + extern "C" void AnopeFini(x *m) \ { \ delete m; \ } #else #define MODULE_INIT(x) \ - extern "C" DllExport Module *init_module(const std::string &modname, const std::string &creator) \ + extern "C" DllExport Module *AnopeInit(const std::string &modname, const std::string &creator) \ { \ return new x(modname, creator); \ } \ - extern "C" DllExport void destroy_module(x *m) \ + extern "C" DllExport void AnopeFini(x *m) \ { \ delete m; \ } #endif /* Miscellaneous definitions. */ -#include "defs.h" -#include "slist.h" +#include "hashcomp.h" /* Pull in the various bits of STL */ #include <iostream> @@ -348,15 +352,16 @@ template<typename T> class Flags class User; class ChannelInfo; class Channel; +class Server; struct EList; +struct Session; typedef struct bandata_ BanData; typedef struct mailinfo_ MailInfo; -typedef struct akill_ Akill; typedef struct exception_ Exception; -typedef struct session_ Session; #include "extensible.h" +#include "threadengine.h" #include "bots.h" #include "opertype.h" #include "modes.h" @@ -374,7 +379,7 @@ struct ircdvars_ { const char *botchanumode; /* Modes set when botserv joins a channel */ int svsnick; /* Supports SVSNICK */ int vhost; /* Supports vhost */ - int sgline; /* Supports SGline */ + int snline; /* Supports SNline */ int sqline; /* Supports SQline */ int szline; /* Supports SZline */ int numservargs; /* Number of Server Args */ @@ -523,7 +528,6 @@ enum AccessLevel /* Access levels for users. */ struct ChanAccess { - uint16 in_use; /* 1 if this entry is in use, else 0 */ int16 level; NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */ time_t last_seen; @@ -544,7 +548,6 @@ enum AutoKickFlag class AutoKick : public Flags<AutoKickFlag> { public: - bool InUse; /* Only one of these can be in use */ std::string mask; NickCore *nc; @@ -572,7 +575,6 @@ enum BadWordType /* Structure used to contain bad words. */ struct BadWord { - bool InUse; std::string word; BadWordType type; }; @@ -617,8 +619,9 @@ struct BadWord #define CA_AUTOOWNER 36 #define CA_OWNER 37 #define CA_OWNERME 38 +#define CA_FOUNDER 39 -#define CA_SIZE 39 +#define CA_SIZE 40 /* BotServ SET flags */ enum BotServFlag @@ -677,48 +680,7 @@ typedef struct { /*************************************************************************/ -/* Server data */ - -typedef enum { - SSYNC_IN_PROGRESS = 0, /* Sync is currently in progress */ - SSYNC_DONE = 1 /* We're in sync */ -} SyncState; - -/** Flags set on servers - */ -enum ServerFlag -{ - SERVER_START, - - /* This server is me */ - SERVER_ISME, - /* This server was juped */ - SERVER_JUPED, - /* This server is the current uplink */ - SERVER_ISUPLINK, - - SERVER_END -}; - -class Server : public Flags<ServerFlag> -{ - public: - Server *next, *prev; - - char *name; /* Server name */ - uint16 hops; /* Hops between services and server */ - char *desc; /* Server description */ - char *suid; /* Server Univeral ID */ - SyncState sync; /* Server sync state (see above) */ - - Server *links; /* Linked list head for linked servers */ - Server *uplink; /* Server which pretends to be the uplink */ -}; - -/*************************************************************************/ - #include "users.h" - /* This structure stocks ban data since it must not be removed when * user is kicked. */ @@ -816,39 +778,6 @@ struct mailinfo_ { /*************************************************************************/ -struct akill_ { - char *user; /* User part of the AKILL */ - char *host; /* Host part of the AKILL */ - - char *by; /* Who set the akill */ - char *reason; /* Why they got akilled */ - - time_t seton; /* When it was set */ - time_t expires; /* When it expires */ -}; - -/*************************************************************************/ - -/* Structure for OperServ SGLINE and SZLINE commands */ - -enum SXLineType -{ - SX_SGLINE, - SX_SQLINE, - SX_SZLINE -}; - -struct SXLine { - char *mask; - char *by; - char *reason; - time_t seton; - time_t expires; -}; - - -/************************************************************************/ - struct exception_ { char *mask; /* Hosts to which this exception applies */ int limit; /* Session limit for exception */ @@ -864,8 +793,11 @@ struct exception_ { /*************************************************************************/ -struct session_ { - Session *prev, *next; +typedef unordered_map_namespace::unordered_map<std::string, Session *, hash_compare_std_string> session_map; +extern CoreExport session_map SessionList; + +struct Session +{ char *host; int count; /* Number of clients with this host */ int hits; /* Number of subsequent kills for a host */ @@ -920,55 +852,6 @@ enum DefconLevel /*************************************************************************/ -/* Types of capab - */ -enum CapabType -{ - CAPAB_BEGIN, - - CAPAB_NOQUIT, - CAPAB_TSMODE, - CAPAB_UNCONNECT, - CAPAB_NICKIP, - CAPAB_NSJOIN, - CAPAB_ZIP, - CAPAB_BURST, - CAPAB_TS3, - CAPAB_TS5, - CAPAB_DKEY, - CAPAB_DOZIP, - CAPAB_DODKEY, - CAPAB_QS, - CAPAB_SCS, - CAPAB_PT4, - CAPAB_UID, - CAPAB_KNOCK, - CAPAB_CLIENT, - CAPAB_IPV6, - CAPAB_SSJ5, - CAPAB_SN2, - CAPAB_VHOST, - CAPAB_TOKEN, - CAPAB_SSJ3, - CAPAB_NICK2, - CAPAB_VL, - CAPAB_TLKEXT, - CAPAB_CHANMODE, - CAPAB_SJB64, - CAPAB_NICKCHARS, - - CAPAB_END -}; - -/* CAPAB stuffs */ -struct CapabInfo -{ - std::string Token; - CapabType Flag; -}; - -/*************************************************************************/ - /** * RFC: defination of a valid nick * nickname = ( letter / special ) *8( letter / digit / special / "-" ) @@ -986,8 +869,12 @@ struct CapabInfo class IRCDProto; struct Uplink; class ServerConfig; + #include "extern.h" -#include "configreader.h" +#include "operserv.h" +#include "mail.h" +#include "servers.h" +#include "config.h" class CoreExport IRCDProto { @@ -1012,8 +899,8 @@ class CoreExport IRCDProto virtual void SendSVSNOOP(const char *, int) { } virtual void SendTopic(BotInfo *, Channel *, const char *, const char *) = 0; virtual void SendVhostDel(User *) { } - virtual void SendAkill(Akill *) = 0; - virtual void SendAkillDel(Akill *) = 0; + virtual void SendAkill(XLine *) = 0; + virtual void SendAkillDel(XLine *) = 0; virtual void SendSVSKill(BotInfo *source, User *user, const char *fmt, ...); virtual void SendSVSMode(User *, int, const char **) = 0; virtual void SendMode(BotInfo *bi, Channel *dest, const char *fmt, ...); @@ -1038,11 +925,11 @@ class CoreExport IRCDProto virtual void SendPing(const char *servname, const char *who); virtual void SendPong(const char *servname, const char *who); virtual void SendJoin(BotInfo *bi, const char *, time_t) = 0; - virtual void SendSQLineDel(const std::string &) = 0; + virtual void SendSQLineDel(XLine *x) = 0; virtual void SendInvite(BotInfo *bi, const char *chan, const char *nick); virtual void SendPart(BotInfo *bi, Channel *chan, const char *fmt, ...); virtual void SendGlobops(BotInfo *source, const char *fmt, ...); - virtual void SendSQLine(const std::string &, const std::string &) = 0; + virtual void SendSQLine(XLine *x) = 0; virtual void SendSquit(const char *servname, const char *message); virtual void SendSVSO(const char *, const char *, const char *) { } virtual void SendChangeBotNick(BotInfo *bi, const char *newnick); @@ -1051,10 +938,10 @@ class CoreExport IRCDProto virtual void SendConnect() = 0; virtual void SendSVSHold(const char *) { } virtual void SendSVSHoldDel(const char *) { } - virtual void SendSGLineDel(SXLine *) { } - virtual void SendSZLineDel(SXLine *) { } - virtual void SendSZLine(SXLine *) { } - virtual void SendSGLine(SXLine *) { } + virtual void SendSGLineDel(XLine *) { } + virtual void SendSZLineDel(XLine *) { } + virtual void SendSZLine(XLine *) { } + virtual void SendSGLine(XLine *) { } virtual void SendBanDel(Channel *, const std::string &) { } virtual void SendSVSModeChan(Channel *, const char *, const char *) { } virtual void SendUnregisteredNick(User *) { } @@ -1137,17 +1024,32 @@ class CoreExport Alog } }; +class Message; // XXX class CoreExport Anope { public: /** Check whether two strings match. - * @param mask The pattern to check (e.g. foo*bar) * @param str The string to check against the pattern (e.g. foobar) + * @param mask The pattern to check (e.g. foo*bar) * @param case_sensitive Whether or not the match is case sensitive, default false. */ static bool Match(const std::string &str, const std::string &mask, bool case_sensitive = false); inline static bool Match(const ci::string &str, const ci::string &mask) { return Match(str.c_str(), mask.c_str(), false); } + + /** Add a message to Anope + * @param name The message name as sent by the IRCd + * @param func A callback function that will be called when this message is received + * @return The new message object + */ + static Message *AddMessage(const std::string &name, int (*func)(const char *source, int ac, const char **av)); + + /** Deletes a message from Anope + * XXX Im not sure what will happen if this function is called indirectly from message function pointed to by this message.. must check + * @param m The message + * @return true if the message was found and deleted, else false + */ + static bool DelMessage(Message *m); }; /*************************************************************************/ @@ -1226,4 +1128,46 @@ class ChanServTimer : public Timer void Tick(time_t); }; +/** A class to process numbered lists (passed to most DEL/LIST/VIEW commands). + * The function HandleNumber is called for every number in the list. Note that + * if descending is true it gets called in descending order. This is so deleting + * the index passed to the function from an array will not cause the other indexes + * passed to the function to be incorrect. This keeps us from having to have an + * 'in use' flag on everything. + */ +class NumberList +{ + private: + std::set<unsigned> numbers; + + bool desc; + public: + /** Processes a numbered list + * @param list The list + * @param descending True to make HandleNumber get called with numbers in descending order + */ + NumberList(const std::string &list, bool descending); + + /** Destructor, does nothing + */ + virtual ~NumberList(); + + /** Should be called after the constructors are done running. This calls the callbacks. + */ + void Process(); + + /** Called with a number from the list + * @param Number The number + */ + virtual void HandleNumber(unsigned Number); + + /** Called when there is an error with the numbered list + * Return false to immediatly stop processing the list and return + * This is all done before we start calling HandleNumber, so no numbers will have been processed yet + * @param list The list + * @return false to stop processing + */ + virtual bool InvalidRange(const std::string &list); +}; + #endif /* SERVICES_H */ diff --git a/include/slist.h b/include/slist.h deleted file mode 100644 index 3377cd48f..000000000 --- a/include/slist.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Header for Services list handler. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for furhter details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#ifndef SLIST_H -#define SLIST_H - -typedef struct slist_ SList; -typedef struct slistopts_ SListOpts; - -struct slist_ { - void **list; - - int16 count; /* Total entries of the list */ - int16 capacity; /* Capacity of the list */ - int16 limit; /* Maximum possible entries on the list */ - - SListOpts *opts; -}; - -struct slistopts_ { - int32 flags; /* Flags for the list. See below. */ - - int (*compareitem) (SList *slist, void *item1, void *item2); /* Called to compare two items */ - int (*isequal) (SList *slist, void *item1, void *item2); /* Called by slist_indexof. item1 can be an arbitrary pointer. */ - void (*freeitem) (SList *slist, void *item); /* Called when an item is removed */ -}; - -#define SLIST_DEFAULT_LIMIT 32767 - -#define SLISTF_NODUP 0x00000001 /* No duplicates in the list. */ -#define SLISTF_SORT 0x00000002 /* Automatically sort the list. Used with compareitem member. */ - -/* Note that number is the index in the array + 1 */ -typedef int (*slist_enumcb_t) (SList *slist, int number, void *item, va_list args); -/* Callback to know whether we can delete the entry. */ -typedef int (*slist_delcheckcb_t) (SList *slist, void *item, va_list args); - -#endif /* SLIST_H */ - diff --git a/include/sockets.h b/include/sockets.h index 3277c1b9f..0da19f951 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -20,6 +20,8 @@ #define CloseSocket close #endif +#define NET_BUFSIZE 65536 + class SocketException : public CoreException { public: diff --git a/include/threadengine.h b/include/threadengine.h new file mode 100644 index 000000000..ab668ea50 --- /dev/null +++ b/include/threadengine.h @@ -0,0 +1,117 @@ +#ifdef _WIN32 +typedef HANDLE ThreadHandle; +typedef CRITICAL_SECTION MutexHandle; +typedef HANDLE CondHandle; +#else +# include <pthread.h> +typedef pthread_t ThreadHandle; +typedef pthread_mutex_t MutexHandle; +typedef pthread_cond_t CondHandle; +#endif + +class ThreadEngine; +class Thread; + +extern CoreExport ThreadEngine threadEngine; + +class ThreadEngine +{ + public: + /** Threadengines constructor + */ + ThreadEngine(); + + /** Threadengines destructor + */ + ~ThreadEngine(); + + /** Start a new thread + * @param thread A pointer to a newley allocated thread + */ + void Start(Thread *thread); +}; + +class Thread : public Extensible +{ + private: + /* Set to true to tell the thread to finish and we are waiting for it */ + bool Exit; + + public: + /* Handle for this thread */ + ThreadHandle Handle; + + /** Threads constructor + */ + Thread(); + + /** Threads destructor + */ + virtual ~Thread(); + + /** Join to the thread, sets the exit state to true + */ + void Join(); + + /** Sets the exit state as true informing the thread we want it to shut down + */ + void SetExitState(); + + /** Returns the exit state of the thread + * @return true if we want to exit + */ + bool GetExitState() const; + + /** Called to run the thread, should be overloaded + */ + virtual void Run(); +}; + +class Mutex +{ + protected: + /* A mutex, used to keep threads in sync */ + MutexHandle mutex; + + public: + /** Constructor + */ + Mutex(); + + /** Destructor + */ + ~Mutex(); + + /** Attempt to lock the mutex, will hang until a lock can be achieved + */ + void Lock(); + + /** Unlock the mutex, it must be locked first + */ + void Unlock(); +}; + +class Condition : public Mutex +{ + private: + /* A condition */ + CondHandle cond; + + public: + /** Constructor + */ + Condition(); + + /** Destructor + */ + ~Condition(); + + /** Called to wakeup the waiter + */ + void Wakeup(); + + /** Called to wait for a Wakeup() call + */ + void Wait(); +}; + diff --git a/include/users.h b/include/users.h index d94dca9bd..880827c73 100644 --- a/include/users.h +++ b/include/users.h @@ -8,6 +8,15 @@ * */ +/* Hash maps used for users. Note UserListByUID will not be used on non-TS6 IRCds, and should never + * be assumed to have users + */ +typedef unordered_map_namespace::unordered_map<ci::string, User *, hash_compare_ci_string> user_map; +typedef unordered_map_namespace::unordered_map<std::string, User *, hash_compare_std_string> user_uid_map; + +extern CoreExport user_map UserListByNick; +extern CoreExport user_uid_map UserListByUID; + struct ChannelContainer { Channel *chan; @@ -27,13 +36,11 @@ class CoreExport User : public Extensible std::string ident; std::string uid; bool OnAccess; /* If the user is on the access list of the nick theyre on */ - std::bitset<128> modes; /* Bitset of mode names the user has set on them */ + Flags<UserModeName> modes; /* Bitset of mode names the user has set on them */ std::map<UserModeName, std::string> Params; /* Map of user modes and the params this user has */ NickCore *nc; /* NickCore account the user is currently loggged in as */ public: // XXX: exposing a tiny bit too much - User *next, *prev; - std::string nick; /* User's current nick */ char *host; /* User's real hostname */ @@ -181,9 +188,10 @@ class CoreExport User : public Extensible virtual const bool IsIdentified(bool CheckNick = false) const; /** Check if the user is recognized for their nick (on the nicks access list) + * @param CheckSecure Only returns true if the user has secure off * @return true or false */ - virtual const bool IsRecognized() const; + virtual const bool IsRecognized(bool CheckSecure = false) const; /** Update the last usermask stored for a user, and check to see if they are recognized */ @@ -247,9 +255,9 @@ class CoreExport User : public Extensible /** Set a string of modes on a user * @param bi The client setting the mode - * @param modes The modes + * @param umodes The modes */ - void SetModes(BotInfo *bi, const char *modes, ...); + void SetModes(BotInfo *bi, const char *umodes, ...); /** Find the channel container for Channel c that the user is on * This is preferred over using FindUser in Channel, as there are usually more users in a channel @@ -258,5 +266,10 @@ class CoreExport User : public Extensible * @return The channel container, or NULL */ ChannelContainer *FindChannel(Channel *c); + + /** Check if the user is protected from kicks and negative mode changes + * @return true or false + */ + bool IsProtected() const; }; diff --git a/include/version.sh b/include/version.sh index 7f14f9e1d..a32c34c5a 100644 --- a/include/version.sh +++ b/include/version.sh @@ -57,16 +57,6 @@ cat >$VERSIONH <<EOF #define VERSION_STRING "$VERSION" #define VERSION_STRING_DOTTED "$VERSIONDOTTED" -#if defined(_WIN32) -# if _MSC_VER >= 1400 -# define VER_OS "W" -# else -# define VER_OS "w" -# endif -#else -# define VER_OS -#endif - #endif EOF diff --git a/include/version.sh.c b/include/version.sh.c index 7750d80f6..261a51ce4 100644 --- a/include/version.sh.c +++ b/include/version.sh.c @@ -188,6 +188,8 @@ void write_version(FILE * fd, const char *input) until_eof = 1; } + if (fdin) + fclose(fdin); } void parse_line(FILE * fd, char *line) diff --git a/install.js b/install.js index de27270cb..9215a10bd 100644 --- a/install.js +++ b/install.js @@ -107,22 +107,22 @@ var installerQuestions = [ }, { 'question' : [ - 'Are you using Visual Studio 2008? If you are, you need to answer yes', + 'Are you using Visual Studio 2010? If you are, you need to answer yes', 'to this question, otherwise CMake will not function properly.' ], - 'short' : 'Using Visual Studio 2008?', + 'short' : 'Using Visual Studio 2010?', 'options' : [ 'yes', 'no' ], 'default_answer' : 'no', 'store_answer' : function(answer) { - installerResponses['Visual Studio 2008'] = answer; + installerResponses['Visual Studio 2010'] = answer; return true; }, 'cmake_argument' : function() { - if (installerResponses['Visual Studio 2008'] == 'yes') - return '-G"Visual Studio 9 2008"'; + if (installerResponses['Visual Studio 2010'] == 'yes') + return '-G"Visual Studio 10"'; else return ''; } @@ -176,9 +176,9 @@ for (x in installerQuestions) installerResponses['Debug'] = 'msvc'; continue; } - if (thisQuestion.short == 'Using Visual Studio 2008?' && installerResponses['Debug'] != 'msvc') + if (thisQuestion.short == 'Using Visual Studio 2010?' && installerResponses['Debug'] != 'msvc') { - installerResponses['Visual Studio 2008'] = 'no'; + installerResponses['Visual Studio 2010'] = 'no'; continue; } while (!validResponse) diff --git a/lang/cat.l b/lang/cat.l index 6f2c72183..b63731df7 100644 --- a/lang/cat.l +++ b/lang/cat.l @@ -373,6 +373,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Ara ets membre en el grup de %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY clau @@ -807,9 +815,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicknames en el grup. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -858,18 +866,15 @@ NICK_SENDPASS_UNAVAILABLE La comanda SENDPASS no esta disponible per l'us d'encriptació. NICK_SENDPASS_SUBJECT Clau pel Nickname (%s) -NICK_SENDPASS_HEAD - Hola, -NICK_SENDPASS_LINE_1 - El teu has demanat rebre la clau pel nickname %s via e-mail. -NICK_SENDPASS_LINE_2 - La clau es %s Per raons de seguretat hauries de canviar-la quant rebis aquest mail. -NICK_SENDPASS_LINE_3 - Si no saps per que aquest mail t'ha estat enviat, per favor ignora'l. -NICK_SENDPASS_LINE_4 - Per favor NO RESPONGUIS a aquest EMAIL! -NICK_SENDPASS_LINE_5 - Administradors de %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK La clau de %s ha estat enviada. @@ -883,9 +888,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -936,17 +940,14 @@ NICK_ENTER_REG_CODE A passcode has been sent to %s, please type %R%s confirm <passcode> to complete registration NICK_REG_MAIL_SUBJECT Nickname Registration (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - You have requested to register the following nickname %s. -NICK_REG_MAIL_LINE_2 + + You have requested to register the nickname %s on %s. Please type " %R%s confirm %s " to complete registration. -NICK_REG_MAIL_LINE_3 - If you don't know why this mail is sent to you, please ignore it silently. -NICK_REG_MAIL_LINE_4 - PLEASE DON'T ANSWER TO THIS MAIL! -NICK_REG_MAIL_LINE_5 + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_GETPASS_PASSCODE_IS Passcode for %s is %s. @@ -1049,6 +1050,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1098,6 +1101,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED El canal %s ha estat eliminat. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET canal opció per ametres @@ -2032,12 +2063,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT New memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 + You've just received a new memo from %s. This is memo number %d. -MEMO_MAIL_TEXT3 - Memo Text: + + Memo text: + + %s ########################################################################### # @@ -2570,22 +2603,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Temps d'expiració per defecte de AKILL: 1 minut OPER_STATS_AKILL_EXPIRE_NONE Temps d'expiració per defecte de AKILL: Sense expiració -OPER_STATS_SGLINE_COUNT - Numero actual de SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Temps d'expiració per defecte de SGLINE: %d dies -OPER_STATS_SGLINE_EXPIRE_DAY - Temps d'expiració per defecte de SGLINE: 1 dia -OPER_STATS_SGLINE_EXPIRE_HOURS - Temps d'expiració per defecte de SGLINE: %d hores -OPER_STATS_SGLINE_EXPIRE_HOUR - Temps d'expiració per defecte de SGLINE: 1 hora -OPER_STATS_SGLINE_EXPIRE_MINS - Temps d'expiració per defecte de SGLINE: %d minuts -OPER_STATS_SGLINE_EXPIRE_MIN - Temps d'expiració per defecte de SGLINE: 1 minut -OPER_STATS_SGLINE_EXPIRE_NONE - Temps d'expiració per defecte de SGLINE: Sense expiració +OPER_STATS_SNLINE_COUNT + Numero actual de SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Temps d'expiració per defecte de SNLINE: %d dies +OPER_STATS_SNLINE_EXPIRE_DAY + Temps d'expiració per defecte de SNLINE: 1 dia +OPER_STATS_SNLINE_EXPIRE_HOURS + Temps d'expiració per defecte de SNLINE: %d hores +OPER_STATS_SNLINE_EXPIRE_HOUR + Temps d'expiració per defecte de SNLINE: 1 hora +OPER_STATS_SNLINE_EXPIRE_MINS + Temps d'expiració per defecte de SNLINE: %d minuts +OPER_STATS_SNLINE_EXPIRE_MIN + Temps d'expiració per defecte de SNLINE: 1 minut +OPER_STATS_SNLINE_EXPIRE_NONE + Temps d'expiració per defecte de SNLINE: Sense expiració OPER_STATS_SQLINE_COUNT Numero actual de SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2713,49 +2746,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR La llista de AKILLs ha estat netegada. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiració] {mascara | llista}[:raó]] -OPER_SGLINE_UNSUPPORTED - Ho sento, SGLINE no esta disponible en aquesta xarxa. -OPER_SGLINE_EXISTS - %s ja existeix a la llista de SGLINEs. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiració] {mascara | llista}[:raó]] +OPER_SNLINE_UNSUPPORTED + Ho sento, SNLINE no esta disponible en aquesta xarxa. +OPER_SNLINE_EXISTS + %s ja existeix a la llista de SNLINEs. +OPER_SNLINE_ALREADY_COVERED %s ja esta cobert per %s. -OPER_SGLINE_REACHED_LIMIT - Ho sento, sols pots tenir %d SGLINEs. -OPER_SGLINE_ADDED - %s afegit a la llista de SGLINEs. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Ho sento, sols pots tenir %d SNLINEs. +OPER_SNLINE_ADDED + %s afegit a la llista de SNLINEs. +OPER_SNLINE_CHANGED Temps d'expiració per a %s canviat. -OPER_SGLINE_NOT_FOUND - %s no trobat a a la llista de SGLINEs. -OPER_SGLINE_NO_MATCH - No existeixen instàncies similars a la llista de SGLINEs. -OPER_SGLINE_DELETED - %s esborrat de la llista de SGLINEs. -OPER_SGLINE_DELETED_ONE - 1 instància esborrada de la llista de SGLINEs. -OPER_SGLINE_DELETED_SEVERAL - %d instàncies esborrades de la llista de SGLINEs. -OPER_SGLINE_LIST_EMPTY - La llista de SGLINEs esta buida. -OPER_SGLINE_LIST_HEADER - Llista actual de SGLINEs: +OPER_SNLINE_NOT_FOUND + %s no trobat a a la llista de SNLINEs. +OPER_SNLINE_NO_MATCH + No existeixen instàncies similars a la llista de SNLINEs. +OPER_SNLINE_DELETED + %s esborrat de la llista de SNLINEs. +OPER_SNLINE_DELETED_ONE + 1 instància esborrada de la llista de SNLINEs. +OPER_SNLINE_DELETED_SEVERAL + %d instàncies esborrades de la llista de SNLINEs. +OPER_SNLINE_LIST_EMPTY + La llista de SNLINEs esta buida. +OPER_SNLINE_LIST_HEADER + Llista actual de SNLINEs: Num Mascara Raó -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Llista actual de SGLINEs: +OPER_SNLINE_VIEW_HEADER + Llista actual de SNLINEs: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (per %s en %s; %s) %s -OPER_SGLINE_CLEAR - La llista de SGLINEs ha estat netegada. +OPER_SNLINE_CLEAR + La llista de SNLINEs ha estat netegada. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3410,6 +3443,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registra un nickname NICK_HELP_CMD_GROUP GROUP Ingresa en un grup +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Per identificar-te amb la teva clau NICK_HELP_CMD_ACCESS @@ -3541,6 +3576,15 @@ NICK_HELP_GROUP Tingues en compte: tots els nicks en un grup comparteixen la mateixa clau. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Sintaxis: IDENTIFY clau @@ -3601,28 +3645,42 @@ NICK_HELP_ACCESS ACCESS LIST Mostra la llista d'accés actual. -NICK_HELP_SET +NICK_HELP_SET_HEAD Sintaxis: SET Opció parametres Estableix varies opcions per a nicknames. Opció pot ser una de: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Estableix el display del teu grup amb serveis +NICK_HELP_CMD_SET_PASSWORD PASSWORD Estableix la clau del teu nickname +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Estableix el llenguatge amb el que els serveis t'enviaran missatges +NICK_HELP_CMD_SET_URL URL Associa una URL amb el teu nickname +NICK_HELP_CMD_SET_EMAIL EMAIL Associa un E-mail amb el teu nickname +NICK_HELP_CMD_SET_ICQ ICQ Associa un numero ICQ amb el teu nickname +NICK_HELP_CMD_SET_GREET GREET Associa un salutació amb el teu nickname +NICK_HELP_CMD_SET_KILL KILL Activa o desactiva la protecció +NICK_HELP_CMD_SET_SECURE SECURE Activa o desactiva la seguretat de nickname +NICK_HELP_CMD_SET_PRIVATE PRIVATE Preveu el teu nickname d'apareixer en un %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Oculta algunes parts de la teva informació +NICK_HELP_CMD_SET_MSG MSG canvia el metode de comunicació amb els serveis +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Per utilitzar aquest comanda, has d'identificar-te primer utilitzant la teva clau (%R%S HELP IDENTIFY @@ -3741,26 +3799,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -4084,8 +4156,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Administradors de serveis poden utilitzar el parametre - ALL amb qualsevol nick. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Sintaxis: LIST patró [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4210,6 +4282,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Registra un canal CHAN_HELP_CMD_SET SET Establir opcions i informació d'un canal +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4313,7 +4387,15 @@ CHAN_HELP_DROP Desenregistra el canal especificat. Nomès pot ser utilitzat pel fundador del canal. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Sintaxis: SET canal opció parametres Li permet al fundador del canal establir varies opcions @@ -4321,44 +4403,67 @@ CHAN_HELP_SET Opcions disponibles: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Estableix el fundador d'un canal +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Estableix el successor d'un canal +CHAN_HELP_CMD_SET_DESC DESC Estableix la descripció del canal +CHAN_HELP_CMD_SET_URL URL Associa una URL amb el canal +CHAN_HELP_CMD_SET_EMAIL EMAIL Associa un E-mail amb el canal +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Estableix un missatge a enviar als usuaris quant entrin al canal +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Estableix com els serveis posen bans en el canal +CHAN_HELP_CMD_SET_MLOCK MLOCK Fixa els Modes de canal on o off +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Rete el topic quant el canal no esta en uso +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Envia una noticia quant les comandes OP/DEOP son utilitzats +CHAN_HELP_CMD_SET_PEACE PEACE Regula l'ús de comandes critiques +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Oculta el canal de la comanda LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Restringeix l'accés al canal +CHAN_HELP_CMD_SET_SECURE SECURE Activa les opcions de seguretat de %S +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Estricte control de l'estatus de chanop +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Estricto control de l'estatus de fundador del canal +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Firma kicks fets amb la comanda KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK El topic sols pot ser canviat amb TOPIC +CHAN_HELP_CMD_SET_XOP XOP Canvia el sistema de privilegis d'usuari +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Escriu %R%S HELP opció per més informació sobre una opció en particular. CHAN_HELP_SET_FOUNDER - Sintaxis: SET canal FOUNDER nick + Sintaxis: %s canal FOUNDER nick Canvia el fundador d'un canal. El nou nickname ha de ser un d'enregistrat. CHAN_HELP_SET_SUCCESSOR - Sintaxis: SET canal SUCCESSOR nick + Sintaxis: %s canal SUCCESSOR nick Canvia el successor d'un canal. Si el nickname fundador caduca o es eliminat mentres el canal esta encara registrat, @@ -4369,13 +4474,13 @@ CHAN_HELP_SET_SUCCESSOR d'enregistrat. CHAN_HELP_SET_DESC - Sintaxis: SET canal DESC descripció + Sintaxis: %s canal DESC descripció Estableix la descripció pel canal, la que es mostrada amb les comandes LIST i INFO. CHAN_HELP_SET_URL - Sintaxis: SET canal URL [url] + Sintaxis: %s canal URL [url] Associa l'URL especificada amb el canal. Aquesta URL sera mostrada quant algu sol.liciti informació sobre el canal amb @@ -4383,7 +4488,7 @@ CHAN_HELP_SET_URL esborra la URL actual pel canal. CHAN_HELP_SET_EMAIL - Sintaxis: SET canal EMAIL [direcció] + Sintaxis: %s canal EMAIL [direcció] Associa l'adreça e-mail especificada amb el canal. Aquesta adreça sera mostrada quant algu sol.liciti @@ -4392,14 +4497,14 @@ CHAN_HELP_SET_EMAIL actual pel canal. CHAN_HELP_SET_ENTRYMSG - Sintaxis: SET canal ENTRYMSG [missatge] + Sintaxis: %s canal ENTRYMSG [missatge] Especifica el missatge que sera enviat via /notice als usuaris quant ingressin al canal. Si cap parametre es especificat, cap missatge sera enviat al entrar al canal. CHAN_HELP_SET_BANTYPE - Sintaxis: SET canal BANTYPE tipus_de_ban + Sintaxis: %s canal BANTYPE tipus_de_ban Especifica el tipus de ban que sera utilitzat pels serveis quant necessitin banear algu @@ -4413,7 +4518,7 @@ CHAN_HELP_SET_BANTYPE 3: ban de la forma *!*usuari@*.domini CHAN_HELP_SET_KEEPTOPIC - Sintaxis: SET canal KEEPTOPIC {ON | OFF} + Sintaxis: %s canal KEEPTOPIC {ON | OFF} Habilita o deshabilita l'opció de retenció de topic per un canal. Quant la retenció de topic esta @@ -4423,7 +4528,7 @@ CHAN_HELP_SET_KEEPTOPIC el canal sigui creat. CHAN_HELP_SET_TOPICLOCK - Sintàxi: SET canal TOPICLOCK {ON | OFF} + Sintàxi: %s canal TOPICLOCK {ON | OFF} Habilita o deshabilita L'opció de fixació de topic per a un canal. Quan la fixació de topic està @@ -4431,7 +4536,7 @@ CHAN_HELP_SET_TOPICLOCK sigui canviat excepte amb la comanda TOPIC. CHAN_HELP_SET_MLOCK - Sintàxi: SET canal MLOCK Modes + Sintàxi: %s canal MLOCK Modes Estableix el paràmetre de fixació de Modes pel canal. %S et permet definir certs Modes de canal per a estar @@ -4469,7 +4574,7 @@ CHAN_HELP_SET_MLOCK són lliures d'estar encesos o apagats. CHAN_HELP_SET_PEACE - Sintàxi: SET canal PEACE {ON | OFF} + Sintàxi: %s canal PEACE {ON | OFF} Habilita o deshabilita l'opció de pau per a un canal. Quan pau està establerta, un usuari no @@ -4478,21 +4583,21 @@ CHAN_HELP_SET_PEACE comandes de %S. CHAN_HELP_SET_PRIVATE - Sintàxi: SET canal PRIVATE {ON | OFF} + Sintàxi: %s canal PRIVATE {ON | OFF} Habilita o deshabilita l'opció de privacitat per a un canal. Quan privacitat està establerta, un %R%S LIST no inclourà el canal en cap llista. CHAN_HELP_SET_RESTRICTED - Sintàxi: SET canal RESTRICTED {ON | OFF} + Sintàxi: %s canal RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Sintàxi: SET canal SECURE {ON | OFF} + Sintàxi: %s canal SECURE {ON | OFF} Habilita o deshabilita les característiques de seguretat de %S per a un canal. Quan SECURE està @@ -4502,7 +4607,7 @@ CHAN_HELP_SET_SECURE accés. CHAN_HELP_SET_SECUREOPS - Sintàxi: SET canal SECUREOPS {ON | OFF} + Sintàxi: %s canal SECUREOPS {ON | OFF} Habilita o deshabilita l'opció seguretat de ops per a un canal. Quan seguretat de ops està establerta, usuaris @@ -4510,7 +4615,7 @@ CHAN_HELP_SET_SECUREOPS obtenir l' estatus d'operador de canal. CHAN_HELP_SET_SECUREFOUNDER - Sintàxi: SET canal SECUREFOUNDER {ON | OFF} + Sintàxi: %s canal SECUREFOUNDER {ON | OFF} Habilita o deshabilita l'opció seguretat de fundador per a un canal. Quan seguretat de fundador està establerta, només @@ -4519,7 +4624,7 @@ CHAN_HELP_SET_SECUREFOUNDER amb %S. CHAN_HELP_SET_SIGNKICK - Sintàxi: SET canal SIGNKICK {ON | LEVEL | OFF} + Sintàxi: %s canal SIGNKICK {ON | LEVEL | OFF} Habilita o deshabilita els kicks firmats per a un canal. Quan SIGNKICK està establert, kicks @@ -4531,7 +4636,7 @@ CHAN_HELP_SET_SIGNKICK firmats. Veure %R%S HELP LEVELS per a més informació. CHAN_HELP_SET_XOP - Sintàxi: SET canal XOP {ON | OFF} + Sintàxi: %s canal XOP {ON | OFF} Habilita o deshabilita el sistema de llistes xOP per a un canal. Quan XOP està establert, has de fer servir les comandes AOP/SOP/VOP @@ -4553,7 +4658,7 @@ CHAN_HELP_SET_XOP problema. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4576,7 +4681,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Sintàxi: SET canal OPNOTICE {ON | OFF} + Sintàxi: %s canal OPNOTICE {ON | OFF} Habilita o deshabilita l'opció de op-notice per a un canal. Quan op-notice està establert, %S enviarà una noticia @@ -5152,14 +5257,6 @@ CHAN_SERVADMIN_HELP_DROP administradors de serveis poden eliminar un canal per el qual no s'haguin identificado. -CHAN_SERVADMIN_HELP_SET - - Administradors de serveis poden tambié establir la - Opció NOEXPIRE, amb la qual s'evita que els canals - expirin. A més, administradors de - serveis poden establir opcions per a qualsevol canal - sense haver d'identificarse per clau en el canal. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Sintàxi: SET canal NOEXPIRE {ON | OFF} @@ -5500,8 +5597,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Mata tots els usuaris en un host OPER_HELP_CMD_AKILL AKILL Manipula la llista AKILL -OPER_HELP_CMD_SGLINE - SGLINE Manipula la llista SGLINE +OPER_HELP_CMD_SNLINE + SNLINE Manipula la llista SNLINE OPER_HELP_CMD_SQLINE SQLINE Manipula la llista SQLINE OPER_HELP_CMD_SZLINE @@ -5710,56 +5807,56 @@ OPER_HELP_AKILL Limitat a operadors de serveis. -OPER_HELP_SGLINE - Sintàxi: SGLINE ADD [+expiració] mascara:raó - SGLINE DEL {mascara | nom | llista} - SGLINE LIST [mascara | llista] - SGLINE VIEW [mascara | llista] - SGLINE CLEAR +OPER_HELP_SNLINE + Sintàxi: SNLINE ADD [+expiració] mascara:raó + SNLINE DEL {mascara | nom | llista} + SNLINE LIST [mascara | llista] + SNLINE VIEW [mascara | llista] + SNLINE CLEAR Permet als operadors de serveis manipular la llista - de SGLINES. Si un usuari amb un nom real concordant - amb una mascara SGLINE s'intenta connectar, els serveis + de SNLINES. Si un usuari amb un nom real concordant + amb una mascara SNLINE s'intenta connectar, els serveis l'impediran aconseguir una sessió d'IRC. - SGLINE ADD afegeix la mascara de nom real especificada a la - llista de SGLINES per la raó especificada (obligatori). + SNLINE ADD afegeix la mascara de nom real especificada a la + llista de SNLINES per la raó especificada (obligatori). expiració es especificada com un sencer seguit de d (dies), h (hores), o m (minuts). Combinacions (com 1h30m) no estan permesses. Si l'especificació de la unitat no es especificada, per defecte són dies (és a dir +30 nomès - significa 30 dies). Per afegir una SGLINE que no caduqui, + significa 30 dies). Per afegir una SNLINE que no caduqui, utilitza +0. Si la mascara de nom real especificada comença amb +, el temp d'expiració ha de ser especificat, encara que sigui el mateix que el per defecte. El temps actual d'expiració - per defecte per SGLINES pot ser consultat amb la comanda + per defecte per SNLINES pot ser consultat amb la comanda STATS AKILL. Nota: Ja que la mascara de nom real pot contenir espais, el separador entre aquest i la raó es un signe de dos punts. - La comanda SGLINE DEL esborra la mascara especificada de la - llista de SGLINES si esta present. Si s'especifica una llista de + La comanda SNLINE DEL esborra la mascara especificada de la + llista de SNLINES si esta present. Si s'especifica una llista de instàncies, aquestes instàncies son esborrades. (Veure l'exemple per LIST especificat més endavant.) - La comanda SGLINE LIST mostra la llista de SGLINES. Si + La comanda SNLINE LIST mostra la llista de SNLINES. Si s'especifica una mascara, nomès les instàncies concordant amb la mascara són mostrades. Si s'especifica una llista de instàncies, nomès aquestes instàncies son mostrades; per exemple: - SGLINE LIST 2-5,7-9 - Llista instàncies de SGLINES enumerades de 2 a 5 i de 7 + SNLINE LIST 2-5,7-9 + Llista instàncies de SNLINES enumerades de 2 a 5 i de 7 a 9. - SGLINE VIEW es una versió més verbal que SGLINE LIST, - i mostrara qui va fegir la SGLINE, la data en la que va + SNLINE VIEW es una versió més verbal que SNLINE LIST, + i mostrara qui va fegir la SNLINE, la data en la que va ser afegida, i quan caducara, a més de la mascara de nom real i la raó. - SGLINE CLEAR neteja totes les instàncies de la llista de - SGLINES. + SNLINE CLEAR neteja totes les instàncies de la llista de + SNLINES. Limitat a operadors de serveis. @@ -391,6 +391,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Du bist jetzt in der Gruppe %s vertreten. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY Passwort @@ -825,9 +833,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d Nicknamen in der Gruppe. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (wird in %s auslaufen) + %s (wird in %s auslaufen) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -877,18 +885,15 @@ NICK_SENDPASS_UNAVAILABLE SENDPASS Befehl nicht verfügbar, da die Verschlüsselung aktiviert ist. NICK_SENDPASS_SUBJECT Nick-Passwort (%s) -NICK_SENDPASS_HEAD +NICK_SENDPASS Hi, -NICK_SENDPASS_LINE_1 - Du wolltest dir dein Passwort von dem Nicknamen %s via eMail schicken lassen. -NICK_SENDPASS_LINE_2 - Das Passwort ist %s Aus Sicherheitsgründen solltest du das Passwort nach Erhalt dieser eMail ändern. -NICK_SENDPASS_LINE_3 - Wenn du nicht weisst, warum du diese Mail erhalten hast, ignoriere sie bitte. -NICK_SENDPASS_LINE_4 - BITTE NICHT AUF DIESE NACHRICHT ANTWORTEN! -NICK_SENDPASS_LINE_5 - %s Administratoren. + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Das Passwort von %s wurde per eMail verschickt. @@ -902,9 +907,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -949,18 +953,15 @@ NICK_ENTER_REG_CODE Ein Password wurde zu %s gesendet, bitte tippe %R%s confirm <passcode> um die Registrierung abzuschließen. NICK_REG_MAIL_SUBJECT Nickname Registrierung (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - Du hast die Registrierung des Nicknamen %s angefordert. -NICK_REG_MAIL_LINE_2 - Bitte tippe " %R%s confirm %s " zum Abschluß der Registrierung ein. -NICK_REG_MAIL_LINE_3 - Wenn du nicht weisst, warum du diese Mail erhalten hast, ignoriere sie bitte. -NICK_REG_MAIL_LINE_4 - BITTE NICHT AUF DIESE NACHRICHT ANTWORTEN! -NICK_REG_MAIL_LINE_5 - Die %s Administratoren. + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Passcode für %s ist %s. NICK_FORCE_REG @@ -1053,6 +1054,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders CHAN_ACCESS_VIEW_XOP_FORMAT %3d %s %s by %s, last seen %s @@ -1119,6 +1122,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Channel %s wurde aus der Datenbank entfernt. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameter +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET Channel Option Parameter @@ -2029,13 +2060,15 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail MEMO_MAIL_SUBJECT Neue Memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 - Du hast gerade eine neue Memo von %s erhalten. Dies ist Memo Nummer %d. -MEMO_MAIL_TEXT3 - Memo Text: + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s + # Standard responses MEMO_RSEND_PLEASE_WAIT Bitte warte %d Sekunden bevor der RSEND Befehl wieder funktioniert. @@ -2541,22 +2574,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Standard Auslaufzeit von AKILLs: 1 Minute OPER_STATS_AKILL_EXPIRE_NONE Standard Auslaufzeit von AKILLs: Kein Auslauf, permanent -OPER_STATS_SGLINE_COUNT - Aktuelle Anzahl von SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Standard Auslaufzeit von SGLINEs: %d Tage -OPER_STATS_SGLINE_EXPIRE_DAY - Standard Auslaufzeit von SGLINEs: 1 Tag -OPER_STATS_SGLINE_EXPIRE_HOURS - Standard Auslaufzeit von SGLINEs: %d Stunden -OPER_STATS_SGLINE_EXPIRE_HOUR - Standard Auslaufzeit von SGLINEs: 1 Stunde -OPER_STATS_SGLINE_EXPIRE_MINS - Standard Auslaufzeit von SGLINEs: %d Minuten -OPER_STATS_SGLINE_EXPIRE_MIN - Standard Auslaufzeit von SGLINEs: 1 Minute -OPER_STATS_SGLINE_EXPIRE_NONE - Standard Auslaufzeit von SGLINEs: Kein Auslauf, permanent +OPER_STATS_SNLINE_COUNT + Aktuelle Anzahl von SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Standard Auslaufzeit von SNLINEs: %d Tage +OPER_STATS_SNLINE_EXPIRE_DAY + Standard Auslaufzeit von SNLINEs: 1 Tag +OPER_STATS_SNLINE_EXPIRE_HOURS + Standard Auslaufzeit von SNLINEs: %d Stunden +OPER_STATS_SNLINE_EXPIRE_HOUR + Standard Auslaufzeit von SNLINEs: 1 Stunde +OPER_STATS_SNLINE_EXPIRE_MINS + Standard Auslaufzeit von SNLINEs: %d Minuten +OPER_STATS_SNLINE_EXPIRE_MIN + Standard Auslaufzeit von SNLINEs: 1 Minute +OPER_STATS_SNLINE_EXPIRE_NONE + Standard Auslaufzeit von SNLINEs: Kein Auslauf, permanent OPER_STATS_SQLINE_COUNT Aktuelle Anzahl von SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2682,49 +2715,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR Die AKILL-Liste wurde geleert. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+Zeit] {Channel} [Grund] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+Zeit] {Hostmask | entry-liste}[:Grund]] -OPER_SGLINE_UNSUPPORTED - SGLINE ist in diesem Netz nicht verfügbar. -OPER_SGLINE_EXISTS - %s existiert bereits auf der SGLINE-Liste. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+Zeit] {Hostmask | entry-liste}[:Grund]] +OPER_SNLINE_UNSUPPORTED + SNLINE ist in diesem Netz nicht verfügbar. +OPER_SNLINE_EXISTS + %s existiert bereits auf der SNLINE-Liste. +OPER_SNLINE_ALREADY_COVERED %s wird bereits durch %s getroffen. -OPER_SGLINE_REACHED_LIMIT - Du kannst nur %d SGLINE's haben. -OPER_SGLINE_ADDED - %s wurde zur SGLINE-Liste hinzugefügt. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Du kannst nur %d SNLINE's haben. +OPER_SNLINE_ADDED + %s wurde zur SNLINE-Liste hinzugefügt. +OPER_SNLINE_CHANGED Auslaufzeit von %s geändert. -OPER_SGLINE_NOT_FOUND - %s wurde nicht auf der SGLINE-Liste gefunden. -OPER_SGLINE_NO_MATCH - Keine entsprechenden Einträge auf der SGLINE-Liste. -OPER_SGLINE_DELETED - %s wurde von der SGLINE-Liste entfernt. -OPER_SGLINE_DELETED_ONE - Es wurde 1 Eintrag aus der SGLINE-Liste entfernt. -OPER_SGLINE_DELETED_SEVERAL - Es wurden %d Einträge aus der SGLINE-Liste entfernt. -OPER_SGLINE_LIST_EMPTY - Die SGLINE-Liste ist leer. -OPER_SGLINE_LIST_HEADER - Aktuelle SGLINE-Liste: +OPER_SNLINE_NOT_FOUND + %s wurde nicht auf der SNLINE-Liste gefunden. +OPER_SNLINE_NO_MATCH + Keine entsprechenden Einträge auf der SNLINE-Liste. +OPER_SNLINE_DELETED + %s wurde von der SNLINE-Liste entfernt. +OPER_SNLINE_DELETED_ONE + Es wurde 1 Eintrag aus der SNLINE-Liste entfernt. +OPER_SNLINE_DELETED_SEVERAL + Es wurden %d Einträge aus der SNLINE-Liste entfernt. +OPER_SNLINE_LIST_EMPTY + Die SNLINE-Liste ist leer. +OPER_SNLINE_LIST_HEADER + Aktuelle SNLINE-Liste: Nummer Maske Grund -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Aktuelle SGLINE-Liste: +OPER_SNLINE_VIEW_HEADER + Aktuelle SNLINE-Liste: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (von %s am %s, %s) %s -OPER_SGLINE_CLEAR - Die SGLINE-Liste wurde geleert. +OPER_SNLINE_CLEAR + Die SNLINE-Liste wurde geleert. # SZLINE responses OPER_SQLINE_SYNTAX @@ -3365,6 +3398,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registriert einen Nicknamen NICK_HELP_CMD_GROUP GROUP Verwaltung von Nickname-Gruppierungen +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Identifizierung des Nicknames NICK_HELP_CMD_ACCESS @@ -3512,6 +3547,15 @@ NICK_HELP_GROUP Achtung: Alle Mitglieder einer Gruppe haben dasselbe Passwort. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Syntax: IDENTIFY Passwort @@ -3578,34 +3622,48 @@ NICK_HELP_ACCESS ACCESS LIST Zeigt die aktuelle Zugriffsliste an. -NICK_HELP_SET +NICK_HELP_SET_HEAD Syntax: SET Option Parameter Stellt verschiedene Optionen zu deinem Nicknamen ein. Option kann eines der folgenden Werte sein: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Ändert den "Ursprung" deiner Gruppe +NICK_HELP_CMD_SET_PASSWORD PASSWORD Setzt das Passwort deines Nicknamens neu +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Stellt die Sprache ein, in der dir die Services antworten sollen. +NICK_HELP_CMD_SET_URL URL Verbindet eine URL mit deinem Nicknamen +NICK_HELP_CMD_SET_ICQ ICQ Trägt deine ICQ-Nummer unter den Infos zu deinem Nicknamen ein. +NICK_HELP_CMD_SET_MSG MSG Ändert die Methode, wie die Services mit dir kommunizieren +NICK_HELP_CMD_SET_EMAIL EMAIL Verbindet eine öffentliche eMail-Adresse mit deinem Nicknamen +NICK_HELP_CMD_SET_GREET GREET Stellt eine Begrüssungsmeldung für deinen Nicknamen ein. +NICK_HELP_CMD_SET_KILL KILL Stellt Kill-Schutz an oder aus. +NICK_HELP_CMD_SET_SECURE SECURE Aktiviert/Deaktiviert den Sicherheitsmodus für deinen Nicknamen +NICK_HELP_CMD_SET_PRIVATE PRIVATE Verhindert das Erscheinen deines Nicknamens auf der Liste von %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Versteckt bestimmte Informationen deines Nicknamens +NICK_HELP_CMD_SET_AUTOOP AUTOOP Sollten Dir die Services automatisch Op-Status geben. +NICK_HELP_SET_TAIL Wenn du eines dieser Optionen nutzen willst, musst du dich vorher identifizeren. @@ -3742,31 +3800,46 @@ NICK_HELP_SET_AUTOOP erlaubt es ChanServ Dir automatisch Op-Status zu geben, wenn Du die Channels betrittst. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Setzt verschiedene Einstellungen für den Nicknamen. Gültig für option ist: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Setzt einen Nicknamen als Ursprung der Nickgruppe +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Setzt das Passwort eines Nicknamens +NICK_HELP_CMD_SASET_URL URL Fügt eine URL dem Nicknamen hinzu +NICK_HELP_CMD_SASET_EMAIL EMAIL Fügt eine Emailadresse dem Nicknamen hinzu +NICK_HELP_CMD_SASET_ICQ ICQ Fügt eine ICQ Nummer dem Nicknamen hinzu +NICK_HELP_CMD_SASET_GREET GREET Fügt eine Begrüssungsnachricht dem Nicknamen hinzu +NICK_HELP_CMD_SASET_KILL KILL Schützt den Nicknamen durch Identifikationszwang +NICK_HELP_CMD_SASET_SECURE SECURE Schaltet die Identifikationssicherheitsfunktion an oder aus +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Verhindert, dass der Nickname im Befehl %R%S LIST auftaucht +NICK_HELP_CMD_SASET_HIDE HIDE Versteckt bestimmte, dem Nicknamen zugeordnete, Informationen +NICK_HELP_CMD_SASET_MSG MSG Bestimmt die Art wie die Services Nachrichten senden +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Verhindert, dass der Nickname nach einer bestimmten Zeit verfällt +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Stellt die Sprache ein, in der die Services dem Nicknamen antworten sollen. +NICK_HELP_CMD_SASET_AUTOOP AUTOOP Sollten die Services dem Nick automatisch seinen Op-Status geben. +NICK_HELP_SASET_TAIL Mit %R%S HELP SASET option können mehr Informationen zu den Einstellungen angefordert werden. Die Einstellungen betreffen den @@ -4123,8 +4196,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Services Administratoren können den ALL Parameter für - jeden beliebigen Nickname benutzen. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Syntax: LIST Muster [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4242,6 +4315,8 @@ CHAN_HELP_CMD_REGISTER CHAN_HELP_CMD_SET SET Bestimmte Channel-Optionen und Informationen einstellen +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Verwaltet die QOP-Liste von einem Channel CHAN_HELP_CMD_AOP @@ -4349,7 +4424,15 @@ CHAN_HELP_DROP Entfernt die Registrierung des angegebenen Channels. Kann nur vom Channel-Founder benutzt werden. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Syntax: SET Channel Option Parameter Erlaubt es dem Channel-Founder bestimmte Optionen @@ -4357,44 +4440,65 @@ CHAN_HELP_SET Verfügbare Optionen: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Stellt den Gründer des Channels ein +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Stellt den Vertreter des Founders ein +CHAN_HELP_CMD_SET_DESC DESC Ändert die Channel-Beschreibung +CHAN_HELP_CMD_SET_URL URL Verbindet eine URL mit dem Channel +CHAN_HELP_CMD_SET_EMAIL EMAIL Verbindet eine eMail-Adresse mit dem Channel +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Stellt eine Begrüssungsmeldung des Channels ein - TOPIC Ändert das Topic im Channel +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Ändert den Ban-Typ, den die Services in dem Channel anwenden +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Topic behalten, wenn Channel nicht benutzt wird +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Topic kann nur durch TOPIC geändert werden +CHAN_HELP_CMD_SET_MLOCK MLOCK Channel-Modes fest einstellen +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Den Channel vom /LIST-Befehl verstecken +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Eingeschränkter Zugriff auf den Channel +CHAN_HELP_CMD_SET_SECURE SECURE Aktiviert %S's Sicherheits-funktionen +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Strengere Kontrolle des Op-Status im Channel +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Strengere Kontrolle des Founder-Status +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Kicks durch ChanServ in dem Channel werden durch den Kicker signiert +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Sendet eine Notice wenn Op/Deop-Befehl benutzt werden +CHAN_HELP_CMD_SET_XOP XOP Schaltet das Listen System ein oder aus +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Tippe %R%S HELP Option für weitere Informationen zu einem bestimmten Befehl. CHAN_HELP_SET_FOUNDER - Syntax: SET Channel FOUNDER Nickname + Syntax: %s Channel FOUNDER Nickname Ändert den Gründer (Founder) eines Channels. Der neue Nickname muss registriert sein. CHAN_HELP_SET_SUCCESSOR - Syntax: SET Channel SUCCESSOR Nickname + Syntax: %s Channel SUCCESSOR Nickname Ändert den Vertreter des Gründers in dem Channel. Wenn der Nickname des Gründers ausläuft oder gedropped wird, @@ -4406,13 +4510,13 @@ CHAN_HELP_SET_SUCCESSOR Der Nickname des Vertreters muss registriert sein. CHAN_HELP_SET_DESC - Syntax: SET Channel DESC Beschreibung + Syntax: %s Channel DESC Beschreibung Ändert die Beschreibung für einen Channel, die bei dem LIST und INFO Befehl angezeigt wird. CHAN_HELP_SET_URL - Syntax: SET Channel URL [Url] + Syntax: %s Channel URL [Url] Verbindet die angegebene URL mit dem Channel. Diese URL wird angezeigt, wenn jemand Informationen @@ -4421,7 +4525,7 @@ CHAN_HELP_SET_URL URL gelöscht. CHAN_HELP_SET_EMAIL - Syntax: SET Channel EMAIL [eMail-Adresse] + Syntax: %s Channel EMAIL [eMail-Adresse] Verbindet die angegebene eMail-Adresse mit dem Channel. Diese eMail-Adresse wird angezeigt, @@ -4430,7 +4534,7 @@ CHAN_HELP_SET_EMAIL angegeben, wird die aktuelle eMail-Adresse gelöscht. CHAN_HELP_SET_ENTRYMSG - Syntax: SET Channel ENTRYMSG [Nachricht] + Syntax: %s Channel ENTRYMSG [Nachricht] Ändert die Nachricht, die User beim Joinen des Channels per /notice bekommen. Wird kein Parameter @@ -4438,7 +4542,7 @@ CHAN_HELP_SET_ENTRYMSG angezeigt. CHAN_HELP_SET_BANTYPE - Syntax: SET Channel BANTYPE Ban-Typ + Syntax: %s Channel BANTYPE Ban-Typ Stellt den Ban-Typ für den Channel ein, den die Services anwenden, wenn sie einen Ban eintragen @@ -4452,7 +4556,7 @@ CHAN_HELP_SET_BANTYPE 3: Ban in der Form *!*user@*.domain CHAN_HELP_SET_KEEPTOPIC - Syntax: SET Channel KEEPTOPIC {ON | OFF} + Syntax: %s Channel KEEPTOPIC {ON | OFF} Aktiviert oder deaktiviert die Topic Wiederherstellung für den Channel. Wird diese Option eingeschaltet, wird das @@ -4462,7 +4566,7 @@ CHAN_HELP_SET_KEEPTOPIC kommt. CHAN_HELP_SET_TOPICLOCK - Syntax: SET Channel TOPICLOCK {ON | OFF} + Syntax: %s Channel TOPICLOCK {ON | OFF} Aktiviert oder deaktiviert die topic lock-Option für den angegebenen Channel. @@ -4471,7 +4575,7 @@ CHAN_HELP_SET_TOPICLOCK ausser es wurde durch TOPIC eingestellt. CHAN_HELP_SET_MLOCK - Syntax: SET Channel MLOCK Modi + Syntax: %s Channel MLOCK Modi Stellt den Mode-Lock-Parameter für den angegebenen Channel ein. %S ermöglicht es dir, einzustellen, @@ -4506,7 +4610,7 @@ CHAN_HELP_SET_MLOCK kann jetzt wahlweise an oder ausgeschaltet werden. CHAN_HELP_SET_PEACE - Syntax: SET Channel PEACE {ON | OFF} + Syntax: %s Channel PEACE {ON | OFF} Aktiviert oder deaktiviert die peace Option. Wenn peace aktiviert ist, kann ein User einen anderen User @@ -4514,21 +4618,21 @@ CHAN_HELP_SET_PEACE %S kicken, bannen oder dessen Channelstatus löschen. CHAN_HELP_SET_PRIVATE - Syntax: SET Channel PRIVATE {ON | OFF} + Syntax: %s Channel PRIVATE {ON | OFF} Schaltet den Privat-Modus für einen Channel an oder aus. Wird er aktiviert, wird der Channel in der Ausgabe von%R%S LIST nicht mehr auftauchen. CHAN_HELP_SET_RESTRICTED - Syntax: SET Channel RESTRICTED {ON | OFF} + Syntax: %s Channel RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Syntax: SET Channel SECURE {ON | OFF} + Syntax: %s Channel SECURE {ON | OFF} Aktiviert oder deaktiviert die Sicherheitsfunktionen von %S für den angegebenen Channel. @@ -4538,7 +4642,7 @@ CHAN_HELP_SET_SECURE in der Zugriffsliste des Channels steht. CHAN_HELP_SET_SECUREOPS - Syntax: SET Channel SECUREOPS {ON | OFF} + Syntax: %s Channel SECUREOPS {ON | OFF} Ändert die Secure-Ops Option für einen Channel. Wird diese Option eingeschaltet, können Nicknamen, @@ -4546,7 +4650,7 @@ CHAN_HELP_SET_SECUREOPS keinen Op-Status erhalten. CHAN_HELP_SET_SECUREFOUNDER - Syntax: SET Channel SECUREFOUNDER {ON | OFF} + Syntax: %s Channel SECUREFOUNDER {ON | OFF} Aktiviert oder deaktiviert die Secure Founder-Option für einen Channel. @@ -4557,7 +4661,7 @@ CHAN_HELP_SET_SECUREFOUNDER hat. CHAN_HELP_SET_SIGNKICK - Syntax: SET Channel SIGNKICK {ON | LEVEL | OFF} + Syntax: %s Channel SIGNKICK {ON | LEVEL | OFF} Aktiviert oder deaktiviert signierte Kicks für einen Channel. Ist SIGNKICK aktiviert, wird der Grund @@ -4570,7 +4674,7 @@ CHAN_HELP_SET_SIGNKICK Siehe %R%S HELP LEVELS für weitere Informationen. CHAN_HELP_SET_XOP - Syntax: SET Channel XOP {ON | OFF} + Syntax: %s Channel XOP {ON | OFF} Aktiviert oder deaktiviert das xOP Listen System für einen Channel. Wenn XOP aktiviert ist, musst du AOP/SOP/VOP @@ -4591,7 +4695,7 @@ CHAN_HELP_SET_XOP jedoch fehlerfrei. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4614,7 +4718,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Syntax: SET Channel OPNOTICE {ON | OFF} + Syntax: %s Channel OPNOTICE {ON | OFF} Aktiviert oder deaktiviert die Op-Notice Option für einen Channel. @@ -5185,16 +5289,6 @@ CHAN_SERVADMIN_HELP_DROP (löschen) ohne sich vorher gegenüber dem Channel als Founder zu identifizieren. -CHAN_SERVADMIN_HELP_SET - - Services Administratoren können zusätzlich die Option NOEXPIRE - an einem Channel setzen, dies verhindert den automatischen - Auslauf des Channels. - - Weiterhin können Services Administratoren Einstellungen - eines Channels verändern, ohne sich vorher für ihn - identifizieren zu müssen. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Syntax: SET Channel NOEXPIRE {ON | OFF} @@ -5539,8 +5633,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Alle User mit einem bestimmten Host killen OPER_HELP_CMD_AKILL AKILL Die AutoKill-Liste bearbeiten -OPER_HELP_CMD_SGLINE - SGLINE Die SGLINE-Liste bearbeiten +OPER_HELP_CMD_SNLINE + SNLINE Die SNLINE-Liste bearbeiten OPER_HELP_CMD_SQLINE SQLINE Die SQLINE-Liste bearbeiten OPER_HELP_CMD_SZLINE @@ -5749,21 +5843,21 @@ OPER_HELP_AKILL AKILL CLEAR entfernt alle Einträge aus der AKILL-Liste. -OPER_HELP_SGLINE - Syntax: SGLINE ADD [+Zeit] Maske:Grund - SGLINE DEL {Maske | entry-num | Liste} - SGLINE LIST [Maske | Liste] - SGLINE VIEW [Maske | Liste] - SGLINE CLEAR +OPER_HELP_SNLINE + Syntax: SNLINE ADD [+Zeit] Maske:Grund + SNLINE DEL {Maske | entry-num | Liste} + SNLINE LIST [Maske | Liste] + SNLINE VIEW [Maske | Liste] + SNLINE CLEAR - Erlaubt Services Operatoren die SGLINE-Liste zu + Erlaubt Services Operatoren die SNLINE-Liste zu bearbeiten. Versucht ein User dessen Realname auf - einen Eintrag in der SGLINE-Liste trifft zu verbinden, + einen Eintrag in der SNLINE-Liste trifft zu verbinden, werden die Services ihn die verbindung auf das IRC Netz nicht ausführen lassen. - SGLINE ADD fügt die angegebene Realnamen-Maske mit - dem Grund (muss angegeben werden) zur SGLINE-Liste + SNLINE ADD fügt die angegebene Realnamen-Maske mit + dem Grund (muss angegeben werden) zur SNLINE-Liste hinzu. Mit Hilfe von Zeit lässt sich eine bestimmte Auslaufzeit dieses Eintrags definieren. Zeit wird durch eine Ganzzahl angegeben, gefolgt von @@ -5771,39 +5865,39 @@ OPER_HELP_SGLINE d (Tage), h (Stunden), oder m (Minuten). Kombinationen (wie zum Beispiel 1h30m) sind nicht zulässig. Wird kein Buchstabe angegeben, wird von Tagen ausgegangen (also +30 - bedeutet dann z.B. 30 Tage). Um einen SGLINE-Eintrag zu + bedeutet dann z.B. 30 Tage). Um einen SNLINE-Eintrag zu erstellen, der nicht ausläuft, benutze +0. Beginnt die Realnamen-Maske mit einem +, an, muss eine Auslaufzeit (expiry) definiert werden, auch wenn es die Standard-Zeit ist. Die Standard-Auslaufzeit für eine - SGLINE kann man unter STATS AKILL finden. + SNLINE kann man unter STATS AKILL finden. Beachte: Da die Realnamen-Maske Leerzeichen enthalten kann, ist das Trennzeichen zwischen der Maske und dem Grund ein Doppelpunkt. - Das SGLINE DEL Befehl entfernt die angegebene Maske - von der SGLINE-Liste, sofern ein solcher Eintag existiert. + Das SNLINE DEL Befehl entfernt die angegebene Maske + von der SNLINE-Liste, sofern ein solcher Eintag existiert. Wird eine Liste von Nummern angegeben, werden diese Einträge entfernt. (Siehe das Beispiel für LIST weiter unten.) - Mit Hilfe von SGLINE LIST wird die SGLINE-Liste + Mit Hilfe von SNLINE LIST wird die SNLINE-Liste angezeigt. Werden Platzhalter (Wildcards) in der Maske angegeben, werden nur die entsprechenden Einträge angezeigt. Die Ausgabe lässt sich ebenfalls durch einen Zahlenbereich begrenzen, wie das Beispiel zeigt: - SGLINE LIST 2-5,7-9 + SNLINE LIST 2-5,7-9 Zeigt nur die Einträge 2 bis 5 und 7 bis 9. - SGLINE VIEW ist eine ausführlichere Version des - SGLINE LIST Befehls und zeigt zusätzlich, wer einen + SNLINE VIEW ist eine ausführlichere Version des + SNLINE LIST Befehls und zeigt zusätzlich, wer einen Eintrag wann erstellt hat, wann er ausläuft und natürlich die user@host Maske mit dem Grund. - SGLINE CLEAR entfernt alle Einträge aus der - SGLINE-Liste. + SNLINE CLEAR entfernt alle Einträge aus der + SNLINE-Liste. OPER_HELP_SQLINE Syntax: SQLINE ADD [+Zeit] Maske Grund @@ -5822,7 +5916,7 @@ OPER_HELP_SQLINE die dieses Feature unterstützen). SQLINE ADD fügt den angegeben Nicknamen mit dem Grund (muss - angegeben werden) zur SGLINE-Liste hinzu. ^_Zeit^_ wird + angegeben werden) zur SNLINE-Liste hinzu. ^_Zeit^_ wird durch eine Ganzzahl angegeben, gefolgt von einem Buchstaben: d (Tage), h (Stunden), oder m (Minuten). Kombinationen sind nicht erlaubt. Wird kein Buchstabe angegeben, diff --git a/lang/en_us.l b/lang/en_us.l index 56fbb8d08..9616558c0 100644 --- a/lang/en_us.l +++ b/lang/en_us.l @@ -363,6 +363,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED You are now in the group of %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY password @@ -790,9 +798,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicknames in the group. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -842,17 +850,14 @@ NICK_SENDPASS_UNAVAILABLE SENDPASS command unavailable because encryption is in use. NICK_SENDPASS_SUBJECT Nickname password (%s) -NICK_SENDPASS_HEAD +NICK_SENDPASS Hi, -NICK_SENDPASS_LINE_1 + You have requested to receive the password of nickname %s by e-mail. -NICK_SENDPASS_LINE_2 - The password is %s for security purposes, you should change it as soon as you receive this mail. -NICK_SENDPASS_LINE_3 - If you don't know why this mail is sent to you, please ignore it silently. -NICK_SENDPASS_LINE_4 - PLEASE DON'T ANSWER TO THIS MAIL! -NICK_SENDPASS_LINE_5 + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_SENDPASS_OK Password of %s has been sent. @@ -864,12 +869,12 @@ NICK_RESETPASS_SUBJECT Reset password request for %s NICK_RESETPASS_MESSAGE Hi, - + You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! - + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_RESETPASS_COMPLETE Password reset email for %s has been sent. @@ -911,24 +916,21 @@ NICK_IS_PREREG This nick is awaiting an e-mail verification code before completing registration. NICK_ENTER_REG_CODE A passcode has been sent to %s, please type %R%s confirm <passcode> to complete registration +NICK_GETPASS_PASSCODE_IS + Passcode for %s is %s. +NICK_FORCE_REG + Nickname %s confirmed NICK_REG_MAIL_SUBJECT Nickname Registration (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - You have requested to register the following nickname %s. -NICK_REG_MAIL_LINE_2 + + You have requested to register the nickname %s on %s. Please type " %R%s confirm %s " to complete registration. -NICK_REG_MAIL_LINE_3 - If you don't know why this mail is sent to you, please ignore it silently. -NICK_REG_MAIL_LINE_4 - PLEASE DON'T ANSWER TO THIS MAIL! -NICK_REG_MAIL_LINE_5 + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. -NICK_GETPASS_PASSCODE_IS - Passcode for %s is %s. -NICK_FORCE_REG - Nickname %s confirmed # Confirm responses NICK_CONFIRM_NOT_FOUND @@ -1026,6 +1028,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1073,6 +1077,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Channel %s has been dropped. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET channel option parameters @@ -1986,12 +2018,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail responses MEMO_MAIL_SUBJECT New memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 + You've just received a new memo from %s. This is memo number %d. -MEMO_MAIL_TEXT3 - Memo Text: + + Memo text: + + %s # RSEND responses MEMO_RSEND_PLEASE_WAIT @@ -2491,22 +2525,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Default AKILL expiry time: 1 minute OPER_STATS_AKILL_EXPIRE_NONE Default AKILL expiry time: No expiration -OPER_STATS_SGLINE_COUNT - Current number of SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Default SGLINE expiry time: %d days -OPER_STATS_SGLINE_EXPIRE_DAY - Default SGLINE expiry time: 1 day -OPER_STATS_SGLINE_EXPIRE_HOURS - Default SGLINE expiry time: %d hours -OPER_STATS_SGLINE_EXPIRE_HOUR - Default SGLINE expiry time: 1 hour -OPER_STATS_SGLINE_EXPIRE_MINS - Default SGLINE expiry time: %d minutes -OPER_STATS_SGLINE_EXPIRE_MIN - Default SGLINE expiry time: 1 minute -OPER_STATS_SGLINE_EXPIRE_NONE - Default SGLINE expiry time: No expiration +OPER_STATS_SNLINE_COUNT + Current number of SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Default SNLINE expiry time: %d days +OPER_STATS_SNLINE_EXPIRE_DAY + Default SNLINE expiry time: 1 day +OPER_STATS_SNLINE_EXPIRE_HOURS + Default SNLINE expiry time: %d hours +OPER_STATS_SNLINE_EXPIRE_HOUR + Default SNLINE expiry time: 1 hour +OPER_STATS_SNLINE_EXPIRE_MINS + Default SNLINE expiry time: %d minutes +OPER_STATS_SNLINE_EXPIRE_MIN + Default SNLINE expiry time: 1 minute +OPER_STATS_SNLINE_EXPIRE_NONE + Default SNLINE expiry time: No expiration OPER_STATS_SQLINE_COUNT Current number of SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2629,46 +2663,46 @@ OPER_AKILL_CLEAR The AKILL list has been cleared. OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiry] {mask | entry-list}[:reason]] -OPER_SGLINE_UNSUPPORTED - Sorry, SGLINE is not available on this network. -OPER_SGLINE_EXISTS - %s already exists on the SGLINE list. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiry] {mask | entry-list}[:reason]] +OPER_SNLINE_UNSUPPORTED + Sorry, SNLINE is not available on this network. +OPER_SNLINE_EXISTS + %s already exists on the SNLINE list. +OPER_SNLINE_ALREADY_COVERED %s is already covered by %s. -OPER_SGLINE_REACHED_LIMIT - Sorry, you can only have %d SGLINEs. -OPER_SGLINE_ADDED - %s added to the SGLINE list. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Sorry, you can only have %d SNLINEs. +OPER_SNLINE_ADDED + %s added to the SNLINE list. +OPER_SNLINE_CHANGED Expiry time of %s changed. -OPER_SGLINE_NOT_FOUND - %s not found on the SGLINE list. -OPER_SGLINE_NO_MATCH - No matching entries on the SGLINE list. -OPER_SGLINE_DELETED - %s deleted from the SGLINE list. -OPER_SGLINE_DELETED_ONE - Deleted 1 entry from the SGLINE list. -OPER_SGLINE_DELETED_SEVERAL - Deleted %d entries from the SGLINE list. -OPER_SGLINE_LIST_EMPTY - SGLINE list is empty. -OPER_SGLINE_LIST_HEADER - Current SGLINE list: +OPER_SNLINE_NOT_FOUND + %s not found on the SNLINE list. +OPER_SNLINE_NO_MATCH + No matching entries on the SNLINE list. +OPER_SNLINE_DELETED + %s deleted from the SNLINE list. +OPER_SNLINE_DELETED_ONE + Deleted 1 entry from the SNLINE list. +OPER_SNLINE_DELETED_SEVERAL + Deleted %d entries from the SNLINE list. +OPER_SNLINE_LIST_EMPTY + SNLINE list is empty. +OPER_SNLINE_LIST_HEADER + Current SNLINE list: Num Mask Reason -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Current SGLINE list: +OPER_SNLINE_VIEW_HEADER + Current SNLINE list: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (by %s on %s; %s) %s -OPER_SGLINE_CLEAR - The SGLINE list has been cleared. +OPER_SNLINE_CLEAR + The SNLINE list has been cleared. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3271,6 +3305,8 @@ NICK_HELP_CMD_REGISTER REGISTER Register a nickname NICK_HELP_CMD_GROUP GROUP Join a group +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Identify yourself with your password NICK_HELP_CMD_ACCESS @@ -3405,6 +3441,15 @@ NICK_HELP_GROUP Note: all the nicknames of a group have the same password. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Syntax: IDENTIFY password @@ -3466,27 +3511,41 @@ NICK_HELP_ACCESS ACCESS LIST Displays the current access list. -NICK_HELP_SET +NICK_HELP_SET_HEAD Syntax: SET option parameters Sets various nickname options. option can be one of: - + +NICK_HELP_CMD_SET_DISPLAY DISPLAY Set the display of your group in Services +NICK_HELP_CMD_SET_PASSWORD PASSWORD Set your nickname password +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to you +NICK_HELP_CMD_SET_URL URL Associate a URL with your nickname +NICK_HELP_CMD_SET_EMAIL EMAIL Associate an E-mail address with your nickname +NICK_HELP_CMD_SET_ICQ ICQ Associate an ICQ number with your nickname +NICK_HELP_CMD_SET_GREET GREET Associate a greet message with your nickname +NICK_HELP_CMD_SET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SET_PRIVATE PRIVATE Prevent your nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. - + +NICK_HELP_SET_TAIL In order to use this command, you must first identify with your password (%R%S HELP IDENTIFY for more information). @@ -3604,27 +3663,42 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: - + +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_AUTOOP AUTOOP Turn autoop on or off +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -3947,7 +4021,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Services Operators may use the ALL parameter with any nick. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Syntax: LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4055,6 +4130,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Register a channel CHAN_HELP_CMD_SET SET Set channel options and information +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4156,7 +4233,15 @@ CHAN_HELP_DROP Unregisters the named channel. Can only be used by channel founder. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Syntax: SET channel option parameters Allows the channel founder to set various channel options @@ -4164,39 +4249,62 @@ CHAN_HELP_SET Available options: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Set the founder of a channel +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Set the successor for a channel +CHAN_HELP_CMD_SET_DESC DESC Set the channel description +CHAN_HELP_CMD_SET_URL URL Associate a URL with the channel +CHAN_HELP_CMD_SET_EMAIL EMAIL Associate an E-mail address with the channel +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Set a message to be sent to users when they enter the channel +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Set how Services make bans on the channel +CHAN_HELP_CMD_SET_MLOCK MLOCK Lock channel modes on or off +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Retain topic when channel is not in use +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Send a notice when OP/DEOP commands are used +CHAN_HELP_CMD_SET_PEACE PEACE Regulate the use of critical commands +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Hide channel from LIST command +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Restrict access to the channel +CHAN_HELP_CMD_SET_SECURE SECURE Activate %S security features +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Stricter control of chanop status +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Stricter control of channel founder status +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Sign kicks that are done with KICK command +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Topic can only be changed with TOPIC +CHAN_HELP_CMD_SET_XOP XOP Toggle the user privilege system +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Type %R%S HELP SET option for more information on a particular option. CHAN_HELP_SET_FOUNDER - Syntax: SET channel FOUNDER nick + Syntax: %s channel FOUNDER nick Changes the founder of a channel. The new nickname must be a registered one. CHAN_HELP_SET_SUCCESSOR - Syntax: SET channel SUCCESSOR nick + Syntax: %s channel SUCCESSOR nick Changes the successor of a channel. If the founder's nickname expires or is dropped while the channel is still @@ -4207,13 +4315,13 @@ CHAN_HELP_SET_SUCCESSOR nickname must be a registered one. CHAN_HELP_SET_DESC - Syntax: SET channel DESC description + Syntax: %s channel DESC description Sets the description for the channel, which shows up with the LIST and INFO commands. CHAN_HELP_SET_URL - Syntax: SET channel URL [url] + Syntax: %s channel URL [url] Associates the given URL with the channel. This URL will be displayed whenever someone requests information on the @@ -4221,7 +4329,7 @@ CHAN_HELP_SET_URL deletes any current URL for the channel. CHAN_HELP_SET_EMAIL - Syntax: SET channel EMAIL [address] + Syntax: %s channel EMAIL [address] Associates the given E-mail address with the channel. This address will be displayed whenever someone requests @@ -4230,14 +4338,14 @@ CHAN_HELP_SET_EMAIL the channel. CHAN_HELP_SET_ENTRYMSG - Syntax: SET channel ENTRYMSG [message] + Syntax: %s channel ENTRYMSG [message] Sets the message which will be sent via /notice to users when they enter the channel. If no parameter is given, causes no message to be sent upon entering the channel. CHAN_HELP_SET_BANTYPE - Syntax: SET channel BANTYPE bantype + Syntax: %s channel BANTYPE bantype Sets the ban type that will be used by services whenever they need to ban someone from your channel. @@ -4250,7 +4358,7 @@ CHAN_HELP_SET_BANTYPE 3: ban in the form *!*user@*.domain CHAN_HELP_SET_KEEPTOPIC - Syntax: SET channel KEEPTOPIC {ON | OFF} + Syntax: %s channel KEEPTOPIC {ON | OFF} Enables or disables the topic retention option for a channel. When topic retention is set, the topic for the @@ -4259,7 +4367,7 @@ CHAN_HELP_SET_KEEPTOPIC next time the channel is created. CHAN_HELP_SET_TOPICLOCK - Syntax: SET channel TOPICLOCK {ON | OFF} + Syntax: %s channel TOPICLOCK {ON | OFF} Enables or disables the topic lock option for a channel. When topic lock is set, %S will not allow the @@ -4267,7 +4375,7 @@ CHAN_HELP_SET_TOPICLOCK command. CHAN_HELP_SET_MLOCK - Syntax: SET channel MLOCK modes + Syntax: %s channel MLOCK modes Sets the mode-lock parameter for the channel. %S allows you to define certain channel modes to be always @@ -4301,7 +4409,7 @@ CHAN_HELP_SET_MLOCK to be either on or off. CHAN_HELP_SET_PEACE - Syntax: SET channel PEACE {ON | OFF} + Syntax: %s channel PEACE {ON | OFF} Enables or disables the peace option for a channel. When peace is set, a user won't be able to kick, @@ -4309,21 +4417,21 @@ CHAN_HELP_SET_PEACE a level superior or equal to his via %S commands. CHAN_HELP_SET_PRIVATE - Syntax: SET channel PRIVATE {ON | OFF} + Syntax: %s channel PRIVATE {ON | OFF} Enables or disables the private option for a channel. When private is set, a %R%S LIST will not include the channel in any lists. CHAN_HELP_SET_RESTRICTED - Syntax: SET channel RESTRICTED {ON | OFF} + Syntax: %s channel RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Syntax: SET channel SECURE {ON | OFF} + Syntax: %s channel SECURE {ON | OFF} Enables or disables %S's security features for a channel. When SECURE is set, only users who have @@ -4332,14 +4440,14 @@ CHAN_HELP_SET_SECURE as controlled by the access list. CHAN_HELP_SET_SECUREOPS - Syntax: SET channel SECUREOPS {ON | OFF} + Syntax: %s channel SECUREOPS {ON | OFF} Enables or disables the secure ops option for a channel. When secure ops is set, users who are not on the userlist will not be allowed chanop status. CHAN_HELP_SET_SECUREFOUNDER - Syntax: SET channel SECUREFOUNDER {ON | OFF} + Syntax: %s channel SECUREFOUNDER {ON | OFF} Enables or disables the secure founder option for a channel. When secure founder is set, only the real founder will be @@ -4347,7 +4455,7 @@ CHAN_HELP_SET_SECUREFOUNDER successor, and not those who are IDENTIFY'd with %S. CHAN_HELP_SET_SIGNKICK - Syntax: SET channel SIGNKICK {ON | LEVEL | OFF} + Syntax: %s channel SIGNKICK {ON | LEVEL | OFF} Enables or disables signed kicks for a channel. When SIGNKICK is set, kicks issued with @@ -4359,7 +4467,7 @@ CHAN_HELP_SET_SIGNKICK kicks signed. See %R%S HELP LEVELS for more information. CHAN_HELP_SET_XOP - Syntax: SET channel XOP {ON | OFF} + Syntax: %s channel XOP {ON | OFF} Enables or disables the xOP lists system for a channel. When XOP is set, you have to use the AOP/SOP/VOP @@ -4381,7 +4489,7 @@ CHAN_HELP_SET_XOP causes no problem though. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4404,7 +4512,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Syntax: SET channel OPNOTICE {ON | OFF} + Syntax: %s channel OPNOTICE {ON | OFF} Enables or disables the op-notice option for a channel. When op-notice is set, %S will send a notice to the @@ -4955,13 +5063,6 @@ CHAN_SERVADMIN_HELP_DROP Unregisters the named channel. Only Services Operators can drop a channel for which they have not identified. -CHAN_SERVADMIN_HELP_SET - - Services Operators can also set the option NOEXPIRE, with - which channels can be prevented from expiring. - Additionally, Services Operators can set options for any - channel without identifying by password for the channel. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Syntax: SET channel NOEXPIRE {ON | OFF} @@ -5269,8 +5370,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Kill all users that have a certain host OPER_HELP_CMD_AKILL AKILL Manipulate the AKILL list -OPER_HELP_CMD_SGLINE - SGLINE Manipulate the SGLINE list +OPER_HELP_CMD_SNLINE + SNLINE Manipulate the SNLINE list OPER_HELP_CMD_SQLINE SQLINE Manipulate the SQLINE list OPER_HELP_CMD_SZLINE @@ -5470,51 +5571,51 @@ OPER_HELP_AKILL AKILL CLEAR clears all entries of the AKILL list. -OPER_HELP_SGLINE - Syntax: SGLINE ADD [+expiry] mask:reason - SGLINE DEL {mask | entry-num | list} - SGLINE LIST [mask | list] - SGLINE VIEW [mask | list] - SGLINE CLEAR +OPER_HELP_SNLINE + Syntax: SNLINE ADD [+expiry] mask:reason + SNLINE DEL {mask | entry-num | list} + SNLINE LIST [mask | list] + SNLINE VIEW [mask | list] + SNLINE CLEAR - Allows Services operators to manipulate the SGLINE list. If - a user with a realname matching an SGLINE mask attempts to + Allows Services operators to manipulate the SNLINE list. If + a user with a realname matching an SNLINE mask attempts to connect, Services will not allow it to pursue his IRC session. - SGLINE ADD adds the given realname mask to the SGLINE + SNLINE ADD adds the given realname mask to the SNLINE list for the given reason (which must be given). expiry is specified as an integer followed by one of d (days), h (hours), or m (minutes). Combinations (such as 1h30m) are not permitted. If a unit specifier is not included, the default is days (so +30 by itself means 30 - days). To add an SGLINE which does not expire, use +0. If the + days). To add an SNLINE which does not expire, use +0. If the realname mask to be added starts with a +, an expiry time must be given, even if it is the same as the default. The - current SGLINE default expiry time can be found with the + current SNLINE default expiry time can be found with the STATS AKILL command. Note: because the realname mask may contain spaces, the separator between it and the reason is a colon. - The SGLINE DEL command removes the given mask from the - SGLINE list if it is present. If a list of entry numbers is + The SNLINE DEL command removes the given mask from the + SNLINE list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.) - The SGLINE LIST command displays the SGLINE list. + The SNLINE LIST command displays the SNLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example: - SGLINE LIST 2-5,7-9 - Lists SGLINE entries numbered 2 through 5 and 7 + SNLINE LIST 2-5,7-9 + Lists SNLINE entries numbered 2 through 5 and 7 through 9. - SGLINE VIEW is a more verbose version of SGLINE LIST, and - will show who added an SGLINE, the date it was added, and when + SNLINE VIEW is a more verbose version of SNLINE LIST, and + will show who added an SNLINE, the date it was added, and when it expires, as well as the realname mask and reason. - SGLINE CLEAR clears all entries of the SGLINE list. + SNLINE CLEAR clears all entries of the SNLINE list. OPER_HELP_SQLINE Syntax: SQLINE ADD [+expiry] mask reason @@ -375,6 +375,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Ahora eres miembro en el grupo de %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY clave @@ -810,9 +818,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicknames en el grupo. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -862,18 +870,15 @@ NICK_SENDPASS_UNAVAILABLE El comando SENDPASS no esta disponible por el uso de encriptacion. NICK_SENDPASS_SUBJECT Clave para el Nickname (%s) -NICK_SENDPASS_HEAD - Hola, -NICK_SENDPASS_LINE_1 - Tu has pedido recibir la clave para el nickname %s por e-mail. -NICK_SENDPASS_LINE_2 - La clave es %s Por razones de seguridad deberas cambiarla en cuanto recibas este mail. -NICK_SENDPASS_LINE_3 - Si no sabes porque este mail ha sido enviado a ti, por favor ignoralo. -NICK_SENDPASS_LINE_4 - POR FAVOR NO RESPONDER A ESTE EMAIL! -NICK_SENDPASS_LINE_5 - Administradores de %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK La clave de %s ha sido enviada. @@ -887,9 +892,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -934,18 +938,15 @@ NICK_ENTER_REG_CODE El password ha sido enviado a %s, tipea %R%s confirm <password> para completar el registro. NICK_REG_MAIL_SUBJECT Registro de Nick (%s) -NICK_REG_MAIL_HEAD - Hola, -NICK_REG_MAIL_LINE_1 - Tu has pedido registrar el nickname %s. -NICK_REG_MAIL_LINE_2 - Tipea " %R%s confirm %s " para completar el registro. -NICK_REG_MAIL_LINE_3 - Si no sabes por que has recibido este email, por favor ignorarlo. -NICK_REG_MAIL_LINE_4 - NO RESPONDAS A ESTE MAIL! -NICK_REG_MAIL_LINE_5 - Administradores de %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS El password para %s es %s. NICK_FORCE_REG @@ -1047,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1096,6 +1099,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED El canal %s ha sido botado. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET canal opcion parametros @@ -2024,12 +2055,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT Nuevo memo -MEMO_MAIL_TEXT1 - Hola %s -MEMO_MAIL_TEXT2 - Acabas de recibir un nuevo memo de %s. Es el memo numero %d. -MEMO_MAIL_TEXT3 - Texto del Memo: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s # Standard responses MEMO_RSEND_PLEASE_WAIT @@ -2541,22 +2574,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Tiempo de expiracion por defecto de AKILL: 1 minuto OPER_STATS_AKILL_EXPIRE_NONE Tiempo de expiracion por defecto de AKILL: Sin expiracion -OPER_STATS_SGLINE_COUNT - Numero actual de SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Tiempo de expiracion por defecto de SGLINE: %d dias -OPER_STATS_SGLINE_EXPIRE_DAY - Tiempo de expiracion por defecto de SGLINE: 1 dia -OPER_STATS_SGLINE_EXPIRE_HOURS - Tiempo de expiracion por defecto de SGLINE: %d horas -OPER_STATS_SGLINE_EXPIRE_HOUR - Tiempo de expiracion por defecto de SGLINE: 1 hora -OPER_STATS_SGLINE_EXPIRE_MINS - Tiempo de expiracion por defecto de SGLINE: %d minutos -OPER_STATS_SGLINE_EXPIRE_MIN - Tiempo de expiracion por defecto de SGLINE: 1 minuto -OPER_STATS_SGLINE_EXPIRE_NONE - Tiempo de expiracion por defecto de SGLINE: Sin expiracion +OPER_STATS_SNLINE_COUNT + Numero actual de SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Tiempo de expiracion por defecto de SNLINE: %d dias +OPER_STATS_SNLINE_EXPIRE_DAY + Tiempo de expiracion por defecto de SNLINE: 1 dia +OPER_STATS_SNLINE_EXPIRE_HOURS + Tiempo de expiracion por defecto de SNLINE: %d horas +OPER_STATS_SNLINE_EXPIRE_HOUR + Tiempo de expiracion por defecto de SNLINE: 1 hora +OPER_STATS_SNLINE_EXPIRE_MINS + Tiempo de expiracion por defecto de SNLINE: %d minutos +OPER_STATS_SNLINE_EXPIRE_MIN + Tiempo de expiracion por defecto de SNLINE: 1 minuto +OPER_STATS_SNLINE_EXPIRE_NONE + Tiempo de expiracion por defecto de SNLINE: Sin expiracion OPER_STATS_SQLINE_COUNT Numero actual de SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2684,49 +2717,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR La lista de AKILLs ha sido limpiada. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiracion] {mascara | lista}[:razon]] -OPER_SGLINE_UNSUPPORTED - Lo siento, SGLINE no esta disponible en esta red. -OPER_SGLINE_EXISTS - %s ya existe en la lista de SGLINEs. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiracion] {mascara | lista}[:razon]] +OPER_SNLINE_UNSUPPORTED + Lo siento, SNLINE no esta disponible en esta red. +OPER_SNLINE_EXISTS + %s ya existe en la lista de SNLINEs. +OPER_SNLINE_ALREADY_COVERED %s ya esta cubierto por %s. -OPER_SGLINE_REACHED_LIMIT - Lo siento, solo puedes tener %d SGLINEs. -OPER_SGLINE_ADDED - %s añadido a la lista de SGLINEs. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Lo siento, solo puedes tener %d SNLINEs. +OPER_SNLINE_ADDED + %s añadido a la lista de SNLINEs. +OPER_SNLINE_CHANGED Tiempo de expiracion para %s cambiado. -OPER_SGLINE_NOT_FOUND - %s no encontrado en la lista de SGLINEs. -OPER_SGLINE_NO_MATCH - No existen instancias similares en la lista de SGLINEs. -OPER_SGLINE_DELETED - %s borrado de la lista de SGLINEs. -OPER_SGLINE_DELETED_ONE - 1 instancia borrada de la lista de SGLINEs. -OPER_SGLINE_DELETED_SEVERAL - %d instancias borradas de la lista de SGLINEs. -OPER_SGLINE_LIST_EMPTY - La lista de SGLINEs esta vacia. -OPER_SGLINE_LIST_HEADER - Lista actual de SGLINEs: +OPER_SNLINE_NOT_FOUND + %s no encontrado en la lista de SNLINEs. +OPER_SNLINE_NO_MATCH + No existen instancias similares en la lista de SNLINEs. +OPER_SNLINE_DELETED + %s borrado de la lista de SNLINEs. +OPER_SNLINE_DELETED_ONE + 1 instancia borrada de la lista de SNLINEs. +OPER_SNLINE_DELETED_SEVERAL + %d instancias borradas de la lista de SNLINEs. +OPER_SNLINE_LIST_EMPTY + La lista de SNLINEs esta vacia. +OPER_SNLINE_LIST_HEADER + Lista actual de SNLINEs: Num Mascara Razon -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Lista actual de SGLINEs: +OPER_SNLINE_VIEW_HEADER + Lista actual de SNLINEs: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (por %s en %s; %s) %s -OPER_SGLINE_CLEAR - La lista de SGLINEs ha sido limpiada. +OPER_SNLINE_CLEAR + La lista de SNLINEs ha sido limpiada. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3382,6 +3415,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registra un nickname NICK_HELP_CMD_GROUP GROUP Ingresa a un grupo +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Para identificarte con tu clave NICK_HELP_CMD_ACCESS @@ -3513,6 +3548,15 @@ NICK_HELP_GROUP Ten en cuenta: todos los nicks en un grupo comparten la misma clave. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Sintaxis: IDENTIFY clave @@ -3573,29 +3617,43 @@ NICK_HELP_ACCESS ACCESS LIST Muestra la lista de acceso actual. -NICK_HELP_SET +NICK_HELP_SET_HEAD Sintaxis: SET opcion parametros Setea varias opciones para nicknames. opcion puede ser una de: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Setea el display de tu grupo con Servicios +NICK_HELP_CMD_SET_PASSWORD PASSWORD Setea la clave de tu nickname +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Setea el lenguaje con el que Servicios te enviara mensajes +NICK_HELP_CMD_SET_URL URL Asocia una URL con tu nickname +NICK_HELP_CMD_SET_EMAIL EMAIL Asocia un E-mail con tu nickname +NICK_HELP_CMD_SET_ICQ ICQ Asocia un numero ICQ con tu nickname +NICK_HELP_CMD_SET_GREET GREET Asocia un saludo con tu nickname +NICK_HELP_CMD_SET_KILL KILL Enciende o apaga la proteccion +NICK_HELP_CMD_SET_SECURE SECURE Enciende o apaga la seguridad de nickname +NICK_HELP_CMD_SET_PRIVATE PRIVATE Previene tu nickname de aparecer en un %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Esconde algunas partes de tu informacion +NICK_HELP_CMD_SET_MSG MSG Cambia el metodo de comunicacion con Servicios +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. - + +NICK_HELP_SET_TAIL Para usar este comando, debes primero identificarte con Servicios usando tu clave (%R%S HELP IDENTIFY para mayor informacion). @@ -3713,26 +3771,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: - + +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -4056,8 +4128,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Administradores de Servicios pueden usar el parametro - ALL con cualquier nick. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Sintaxis: LIST patron [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4181,6 +4253,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Registra un canal CHAN_HELP_CMD_SET SET Setea opciones e informacion de un canal +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4284,7 +4358,15 @@ CHAN_HELP_DROP Desregistra el canal dado. Solo puede ser usado por el fundador del canal. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Sintaxis: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Sintaxis: SET canal opcion parametros Le permite al fundador del canal setear varias opciones @@ -4292,45 +4374,68 @@ CHAN_HELP_SET Opciones disponibles: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Setea el fundador de un canal +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Setea el sucesor de un canal +CHAN_HELP_CMD_SET_DESC DESC Setea la descripcion del canal +CHAN_HELP_CMD_SET_URL URL Asocia una URL con el canal +CHAN_HELP_CMD_SET_EMAIL EMAIL Asocia un E-mail con el canal +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Setea un mensaje a enviar a los usuarios cuando entren al canal +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Setea como los Servicios ponen bans en el canal +CHAN_HELP_CMD_SET_MLOCK MLOCK Fija los modos de canal on u off +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Retiene el topic cuando el canal no esta en uso +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Envia una noticia cuando los comandos OP/DEOP son usados +CHAN_HELP_CMD_SET_PEACE PEACE Regula el uso de comandos criticos +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Esconde el canal del comando LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Restrinje el acceso al canal +CHAN_HELP_CMD_SET_SECURE SECURE Activa las opciones de seguridad de %S +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Estricto control del estatus de chanop +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Estricto control del estatus de fundador de canal +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Firma kicks hechos con el comando KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK El topic solo puede ser cambiado con TOPIC +CHAN_HELP_CMD_SET_XOP XOP Cambia el sistema de privilegios de usuario +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent - +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring + +CHAN_HELP_SET_TAIL Tipea %R%S HELP opcion para mayor informacion acerca de una opcion en particular. CHAN_HELP_SET_FOUNDER - Sintaxis: SET canal FOUNDER nick + Sintaxis: %s canal FOUNDER nick Cambia el fundador de un canal. El nuevo nickname debe ser uno registrado. CHAN_HELP_SET_SUCCESSOR - Sintaxis: SET canal SUCCESSOR nick + Sintaxis: %s canal SUCCESSOR nick Cambia el sucesor de un canal. Si el nickname fundador expira o es botado mientras el canal esta aun registrado, @@ -4341,13 +4446,13 @@ CHAN_HELP_SET_SUCCESSOR registrado. CHAN_HELP_SET_DESC - Sintaxis: SET canal DESC descripcion + Sintaxis: %s canal DESC descripcion Setea la descripcion para el canal, la que es mostrada con los comandos LIST y INFO. CHAN_HELP_SET_URL - Sintaxis: SET canal URL [url] + Sintaxis: %s canal URL [url] Asocia la URL dada con el canal. Esta URL sera mostrada cuando alguien solicite informacion sobre el canal con @@ -4355,7 +4460,7 @@ CHAN_HELP_SET_URL borra la URL actual para el canal. CHAN_HELP_SET_EMAIL - Sintaxis: SET canal EMAIL [direccion] + Sintaxis: %s canal EMAIL [direccion] Asocia la direccion E-mail dada con el canal. Esta direccion sera mostrada cuando alguien solicite @@ -4364,14 +4469,14 @@ CHAN_HELP_SET_EMAIL actual para el canal. CHAN_HELP_SET_ENTRYMSG - Sintaxis: SET canal ENTRYMSG [mensaje] + Sintaxis: %s canal ENTRYMSG [mensaje] Setea el mensaje que sera enviado via /notice a los usuarios cuando ingresen al canal. Si ningun parametro es dado, ningun mensaje sera enviado al entrar al canal. CHAN_HELP_SET_BANTYPE - Sintaxis: SET canal BANTYPE tipo_de_ban + Sintaxis: %s canal BANTYPE tipo_de_ban Setea el tipo de ban que sera usado por los Servicios cuando necesiten banear a alguien @@ -4385,7 +4490,7 @@ CHAN_HELP_SET_BANTYPE 3: ban en la forma *!*usuario@*.dominio CHAN_HELP_SET_KEEPTOPIC - Sintaxis: SET canal KEEPTOPIC {ON | OFF} + Sintaxis: %s canal KEEPTOPIC {ON | OFF} Habilita o deshabilita la opcion de retencion de topic para un canal. Cuando la retencion de topic esta @@ -4395,7 +4500,7 @@ CHAN_HELP_SET_KEEPTOPIC el canal sea creado. CHAN_HELP_SET_TOPICLOCK - Sintaxis: SET canal TOPICLOCK {ON | OFF} + Sintaxis: %s canal TOPICLOCK {ON | OFF} Abilita o desabilita la opcion de fijacion de topic para un canal. Cuando la fijacion de topic esta @@ -4403,7 +4508,7 @@ CHAN_HELP_SET_TOPICLOCK sea cambiado excepto con el comando TOPIC. CHAN_HELP_SET_MLOCK - Sintaxis: SET canal MLOCK modos + Sintaxis: %s canal MLOCK modos Setea el parametro de fijacion de modos para el canal. %S te permite definir ciertos modos de canal para estar @@ -4441,7 +4546,7 @@ CHAN_HELP_SET_MLOCK son libres de estar encendidos o apagados. CHAN_HELP_SET_PEACE - Sintaxis: SET canal PEACE {ON | OFF} + Sintaxis: %s canal PEACE {ON | OFF} Habilita o deshabilita la opcion de paz para un canal. Cuando paz esta seteada, un usuario no @@ -4450,21 +4555,21 @@ CHAN_HELP_SET_PEACE comandos de %S. CHAN_HELP_SET_PRIVATE - Sintaxis: SET canal PRIVATE {ON | OFF} + Sintaxis: %s canal PRIVATE {ON | OFF} Habilita o deshabilita la opcion de privacidad para un canal. Cuando privacidad esta seteada, un %R%S LIST no incluira el canal en ninguna lista. CHAN_HELP_SET_RESTRICTED - Sintaxis: SET canal RESTRICTED {ON | OFF} + Sintaxis: %s canal RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Sintaxis: SET canal SECURE {ON | OFF} + Sintaxis: %s canal SECURE {ON | OFF} Habilita o deshabilita las caracteristicas de seguridad de %S para un canal. Cuando SECURE esta @@ -4474,7 +4579,7 @@ CHAN_HELP_SET_SECURE acceso. CHAN_HELP_SET_SECUREOPS - Sintaxis: SET canal SECUREOPS {ON | OFF} + Sintaxis: %s canal SECUREOPS {ON | OFF} Habilita o deshabilita la opcion seguridad de ops para un canal. Cuando seguridad de ops esta seteada, usuarios @@ -4482,7 +4587,7 @@ CHAN_HELP_SET_SECUREOPS obtener el status de operador de canal. CHAN_HELP_SET_SECUREFOUNDER - Sintaxis: SET canal SECUREFOUNDER {ON | OFF} + Sintaxis: %s canal SECUREFOUNDER {ON | OFF} Habilita o deshabilita la opcion seguridad de fundador para un canal. Cuando seguridad de fundador esta seteada, solo @@ -4491,7 +4596,7 @@ CHAN_HELP_SET_SECUREFOUNDER con %S. CHAN_HELP_SET_SIGNKICK - Sintaxis: SET canal SIGNKICK {ON | LEVEL | OFF} + Sintaxis: %s canal SIGNKICK {ON | LEVEL | OFF} Habilita o deshabilita los kicks firmados para un canal. Cuando SIGNKICK esta seteado, kicks @@ -4503,7 +4608,7 @@ CHAN_HELP_SET_SIGNKICK firmados. Ver %R%S HELP LEVELS para mayor informacion. CHAN_HELP_SET_XOP - Sintaxis: SET canal XOP {ON | OFF} + Sintaxis: %s canal XOP {ON | OFF} Habilita o deshabilita el sistema de listas xOP para un canal. Cuando XOP esta seteado, debes usar los comandos AOP/SOP/VOP @@ -4525,7 +4630,7 @@ CHAN_HELP_SET_XOP problema alguno. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4548,7 +4653,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Sintaxis: SET canal OPNOTICE {ON | OFF} + Sintaxis: %s canal OPNOTICE {ON | OFF} Habilita o deshabilita la opcion de op-notice para un canal. Cuando op-notice esta seteado, %S enviara una noticia @@ -5117,14 +5222,6 @@ CHAN_SERVADMIN_HELP_DROP administradores de Servicios pueden botar un canal por el cual no se hayan identificado. -CHAN_SERVADMIN_HELP_SET - - Administradores de Servicios pueden tambien setear la - opcion NOEXPIRE, con la cual canales pueden ser - prevenidos a expirar. Ademas, administradores de - Servicios pueden setear opciones para cualquier canal - sin tener que identificarse por clave en el canal. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Sintaxis: SET canal NOEXPIRE {ON | OFF} @@ -5469,8 +5566,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Killea todos los usuarios en un host OPER_HELP_CMD_AKILL AKILL Manipula la lista AKILL -OPER_HELP_CMD_SGLINE - SGLINE Manipula la lista SGLINE +OPER_HELP_CMD_SNLINE + SNLINE Manipula la lista SNLINE OPER_HELP_CMD_SQLINE SQLINE Manipula la lista SQLINE OPER_HELP_CMD_SZLINE @@ -5683,56 +5780,56 @@ OPER_HELP_AKILL Limitado a Operadores de Servicios. -OPER_HELP_SGLINE - Sintaxis: SGLINE ADD [+expiracion] mascara:razon - SGLINE DEL {mascara | numero | lista} - SGLINE LIST [mascara | lista] - SGLINE VIEW [mascara | lista] - SGLINE CLEAR +OPER_HELP_SNLINE + Sintaxis: SNLINE ADD [+expiracion] mascara:razon + SNLINE DEL {mascara | numero | lista} + SNLINE LIST [mascara | lista] + SNLINE VIEW [mascara | lista] + SNLINE CLEAR Permite a los operadores de Servicios a manipular la lista - de SGLINES. Si un usuario con un nombre real concordando - una mascara SGLINE se intenta conectar, los Servicios le + de SNLINES. Si un usuario con un nombre real concordando + una mascara SNLINE se intenta conectar, los Servicios le impediran conseguir una sesion de IRC. - SGLINE ADD añade la mascara de nombre real dada a la - lista de SGLINES por la razon dada (la que debe ser + SNLINE ADD añade la mascara de nombre real dada a la + lista de SNLINES por la razon dada (la que debe ser dada). expiracion es especificada como un entero seguido de uno de d (dias), h (horas), o m (minutos). Combinaciones (como 1h30m) no estan permitidas. Si la especificacion de la unidad no es incluida, por defecto son dias (osea +30 por si solo - significa 30 dias). Para añadir una SGLINE que no expire, + significa 30 dias). Para añadir una SNLINE que no expire, usa +0. Si la mascara de nombre real dada empieza con +, el tiempo de expiracion debe ser dado, aun si es el mismo que el por defecto. El tiempo actual de expiracion - por defecto para SGLINES puede ser visto con el comando + por defecto para SNLINES puede ser visto con el comando STATS AKILL. Notese: Ya que la mascara de nombre real puede contener espacios, el separador entre esta y la razon es un signo de dos puntos. - El comando SGLINE DEL remueve la mascara dada de la - lista de SGLINES si esta presente. Si una lista de + El comando SNLINE DEL remueve la mascara dada de la + lista de SNLINES si esta presente. Si una lista de instancias es dada, esas instancias son borradas. (Ver el ejemplo para LIST mas abajo.) - El comando SGLINE LIST muestra la lista de SGLINES. Si + El comando SNLINE LIST muestra la lista de SNLINES. Si una mascara es dada, solo las instancias concordando con la mascara son mostradas. Si una lista de instancias es dada, solo esas instancias son mostradas; por ejemplo: - SGLINE LIST 2-5,7-9 - Lista instancias de SGLINES enumeradas 2 a 5 y 7 + SNLINE LIST 2-5,7-9 + Lista instancias de SNLINES enumeradas 2 a 5 y 7 a 9. - SGLINE VIEW es una version mas verbal que SGLINE LIST, - y mostrara quien añadio la SGLINE, la fecha en la que fue + SNLINE VIEW es una version mas verbal que SNLINE LIST, + y mostrara quien añadio la SNLINE, la fecha en la que fue añadida, y cuando expira, ademas de la mascara de nombre real y la razon. - SGLINE CLEAR limpia todas las instancias de la lista de - SGLINES. + SNLINE CLEAR limpia todas las instancias de la lista de + SNLINES. Limitado a operadores de Servicios. @@ -377,6 +377,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Vous êtes maintenant dans le groupe de %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY motdepasse @@ -817,9 +825,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d pseudos dans le groupe. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expire le %s) + %s (expire le %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -869,18 +877,15 @@ NICK_SENDPASS_UNAVAILABLE La commande SENDPASS est indisponible car le cryptage est utilisé. NICK_SENDPASS_SUBJECT Mot de passe du pseudo %s -NICK_SENDPASS_HEAD - Bonjour, -NICK_SENDPASS_LINE_1 - Vous avez demandé à recevoir le mot de passe du pseudo %s par e-mail. -NICK_SENDPASS_LINE_2 - Le mot de passe est %s . Pour des raisons de sécurité, vous devriez le changer dès que vous lisez cet e-mail. -NICK_SENDPASS_LINE_3 - Si vous ne savez pas de quoi il retourne dans cet e-mail, il s'agit probablement d'une erreur, nous vous prions de nous excuser et vous demandons d'ignorer cet e-mail. -NICK_SENDPASS_LINE_4 - NE REPONDEZ PAS À CE MAIL! -NICK_SENDPASS_LINE_5 - Les administrateurs de %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Le mot de passe de %s a été envoyé. @@ -894,9 +899,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -947,18 +951,15 @@ NICK_ENTER_REG_CODE Un passcode a été envoyé à %s, merci de taper %R%s confirm <passcode> une fois que vous l'aurez reçu pour compléter l'enregistrement. NICK_REG_MAIL_SUBJECT Enregistrement d'un pseudo (%s) -NICK_REG_MAIL_HEAD - Bonjour, -NICK_REG_MAIL_LINE_1 - Vous venez de demander l'enregistrement du pseudo %s. -NICK_REG_MAIL_LINE_2 - Veuillez tapez " %R%s confirm %s " sur IRC afin de valider l'enregistrement. -NICK_REG_MAIL_LINE_3 - Si vous ne savez pas pourquoi vous avez reçu cet email, ignorez-le. -NICK_REG_MAIL_LINE_4 - NE REPONDEZ PAS À CE MESSAGE. -NICK_REG_MAIL_LINE_5 - Les administrateurs de %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Le passcode pour %s est %s. NICK_FORCE_REG @@ -1058,6 +1059,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1108,6 +1111,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Le canal %s a été effacé. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET canal option paramètres @@ -2039,12 +2070,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT Nouveau mémo -MEMO_MAIL_TEXT1 - Bonjour %s, -MEMO_MAIL_TEXT2 - Vous venez de recevoir un mémo de %s. Le numéro de ce mémo est %d. -MEMO_MAIL_TEXT3 - Mémo: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s ########################################################################### # @@ -2591,22 +2624,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Temps d'échéance des AKILLs par défaut: 1 minute OPER_STATS_AKILL_EXPIRE_NONE Temps d'échéance des AKILLs par défaut: Pas d'échéance -OPER_STATS_SGLINE_COUNT - Nombre de SGLINEs actuel: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Temps d'échéance des SGLINEs par défaut: %d jours -OPER_STATS_SGLINE_EXPIRE_DAY - Temps d'échéance des SGLINEs par défaut: 1 jour -OPER_STATS_SGLINE_EXPIRE_HOURS - Temps d'échéance des SGLINEs par défaut: %d heures -OPER_STATS_SGLINE_EXPIRE_HOUR - Temps d'échéance des SGLINEs par défaut: 1 heure -OPER_STATS_SGLINE_EXPIRE_MINS - Temps d'échéance des SGLINEs par défaut: %d minutes -OPER_STATS_SGLINE_EXPIRE_MIN - Temps d'échéance des SGLINEs par défaut: 1 minute -OPER_STATS_SGLINE_EXPIRE_NONE - Temps d'échéance des SGLINEs par défaut: Pas d'échéance +OPER_STATS_SNLINE_COUNT + Nombre de SNLINEs actuel: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Temps d'échéance des SNLINEs par défaut: %d jours +OPER_STATS_SNLINE_EXPIRE_DAY + Temps d'échéance des SNLINEs par défaut: 1 jour +OPER_STATS_SNLINE_EXPIRE_HOURS + Temps d'échéance des SNLINEs par défaut: %d heures +OPER_STATS_SNLINE_EXPIRE_HOUR + Temps d'échéance des SNLINEs par défaut: 1 heure +OPER_STATS_SNLINE_EXPIRE_MINS + Temps d'échéance des SNLINEs par défaut: %d minutes +OPER_STATS_SNLINE_EXPIRE_MIN + Temps d'échéance des SNLINEs par défaut: 1 minute +OPER_STATS_SNLINE_EXPIRE_NONE + Temps d'échéance des SNLINEs par défaut: Pas d'échéance OPER_STATS_SQLINE_COUNT Nombre de SQLINEs actuel: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2734,49 +2767,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR La liste d'AKILL a été vidée. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#canal} [raison] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+échéance] {masque | liste d'entrées} [raison]] -OPER_SGLINE_UNSUPPORTED - Désolé, SGLINE n'est pas disponible sur ce réseau. -OPER_SGLINE_EXISTS - %s existe déjà sur la liste de SGLINEs. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+échéance] {masque | liste d'entrées} [raison]] +OPER_SNLINE_UNSUPPORTED + Désolé, SNLINE n'est pas disponible sur ce réseau. +OPER_SNLINE_EXISTS + %s existe déjà sur la liste de SNLINEs. +OPER_SNLINE_ALREADY_COVERED %s est déjà couvert par %s. -OPER_SGLINE_REACHED_LIMIT - Désolé, vous ne pouvez avoir que %d SGLINEs. -OPER_SGLINE_ADDED - %s ajouté à la liste de SGLINEs. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Désolé, vous ne pouvez avoir que %d SNLINEs. +OPER_SNLINE_ADDED + %s ajouté à la liste de SNLINEs. +OPER_SNLINE_CHANGED L'échéance de %s a été changée. -OPER_SGLINE_NOT_FOUND - %s introuvable sur la liste de SGLINEs. -OPER_SGLINE_NO_MATCH - Aucune entrée correspondante sur la liste de SGLINEs. -OPER_SGLINE_DELETED - %s supprimé de la liste de SGLINEs. -OPER_SGLINE_DELETED_ONE - 1 entrée supprimée de la liste de SGLINEs. -OPER_SGLINE_DELETED_SEVERAL - %d entrées supprimées de la liste de SGLINEs. -OPER_SGLINE_LIST_EMPTY - La liste de SGLINEs est vide. -OPER_SGLINE_LIST_HEADER - Liste de SGLINEs actuelle: +OPER_SNLINE_NOT_FOUND + %s introuvable sur la liste de SNLINEs. +OPER_SNLINE_NO_MATCH + Aucune entrée correspondante sur la liste de SNLINEs. +OPER_SNLINE_DELETED + %s supprimé de la liste de SNLINEs. +OPER_SNLINE_DELETED_ONE + 1 entrée supprimée de la liste de SNLINEs. +OPER_SNLINE_DELETED_SEVERAL + %d entrées supprimées de la liste de SNLINEs. +OPER_SNLINE_LIST_EMPTY + La liste de SNLINEs est vide. +OPER_SNLINE_LIST_HEADER + Liste de SNLINEs actuelle: Num Masque Raison -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Liste de SGLINEs actuelle: +OPER_SNLINE_VIEW_HEADER + Liste de SNLINEs actuelle: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (par %s le %s; %s) %s -OPER_SGLINE_CLEAR - La liste de SGLINEs a été vidée. +OPER_SNLINE_CLEAR + La liste de SNLINEs a été vidée. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3431,6 +3464,8 @@ NICK_HELP_CMD_REGISTER REGISTER Enregistre un pseudo NICK_HELP_CMD_GROUP GROUP Joint un groupe +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Vous identifie avec votre mot de passe NICK_HELP_CMD_ACCESS @@ -3575,6 +3610,15 @@ NICK_HELP_IDENTIFY mot de passe est celui que vous avez donné avec la commande REGISTER. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_UPDATE Syntax: UPDATE @@ -3628,27 +3672,41 @@ NICK_HELP_ACCESS ACCESS LIST Affiche votre liste d'accès. -NICK_HELP_SET +NICK_HELP_SET_HEAD Syntaxe: SET option paramètres Configure diverses options du pseudo. option peut être: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Change l'affichage de votre groupe dans les services +NICK_HELP_CMD_SET_PASSWORD PASSWORD Change le mot de passe de votre pseudo +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Change la langue dans laquelle les Services vous envoient leurs messages +NICK_HELP_CMD_SET_URL URL Associe une adresse de site à votre pseudo +NICK_HELP_CMD_SET_EMAIL EMAIL Associe une e-mail à votre pseudo +NICK_HELP_CMD_SET_ICQ ICQ Associe un numéro ICQ à votre pseudo +NICK_HELP_CMD_SET_GREET GREET Associe un message d'accueil à votre pseudo +NICK_HELP_CMD_SET_KILL KILL Active ou désactive la protection +NICK_HELP_CMD_SET_SECURE SECURE Active ou désactive la sécurité du pseudo +NICK_HELP_CMD_SET_PRIVATE PRIVATE Empêche votre pseudo d'être affiché par %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Cache certaines parties des informations du pseudo +NICK_HELP_CMD_SET_MSG MSG Change le mode de communication des Services +NICK_HELP_CMD_SET_AUTOOP AUTOOP Demande à Services de vous rendre automatiquement OP. +NICK_HELP_SET_TAIL Pour utiliser cette commande, vous devez d'abord vous identifier avec votre mot de passe (%R%S HELP @@ -3767,26 +3825,40 @@ NICK_HELP_SET_AUTOOP Positionnez sur ON pour permettre à ChanServ de le faire quand vous entrez dans un canal. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntaxe: SASET pseudo option parametres. Configure plusieurs options sur un pseudo. option doit être l'une ci-dessous: - + +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Affiche les pseudos du groupe du pseudo donné +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Change le mot de passe du pseudo donné +NICK_HELP_CMD_SASET_URL URL Associe une url au pseudo donné +NICK_HELP_CMD_SASET_EMAIL EMAIL Associe une email au pseudo donné +NICK_HELP_CMD_SASET_ICQ ICQ Associe un compte ICQ au pseudo donné +NICK_HELP_CMD_SASET_GREET GREET Associe un message d'accueil au pseudo donné +NICK_HELP_CMD_SASET_KILL KILL Active ou désactive l'option kill du pseudo donné +NICK_HELP_CMD_SASET_SECURE SECURE Active ou désactive la securité du pseudo donné +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Empêche le pseudo d'apparaître dans un %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Cache certaines informations personnelles du pseudo +NICK_HELP_CMD_SASET_MSG MSG Change le mode de communication des Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Empêche le pseudo d'expirer +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Défini la langue que Services utilisera dans les messages qu'il vous envoie. +NICK_HELP_SASET_TAIL Taper %R%S HELP SASET option pour plus d'informations sur une option spécifique. L'option devra être mise avec le pseudo @@ -4118,8 +4190,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Les services operators peuvent utiliser le paramètre ALL - avec n'importe quel pseudo. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Syntaxe: LIST modèle [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4242,6 +4314,8 @@ CHAN_HELP_CMD_REGISTER CHAN_HELP_CMD_SET SET Configure les options et informations du canal +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4346,7 +4420,15 @@ CHAN_HELP_DROP Efface le canal donné. Peut uniquement être utilisé par le propriétaire du canal. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntaxe: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Syntaxe: SET canal option paramètres Permet au propriétaire du canal de configurer diverses options @@ -4354,44 +4436,66 @@ CHAN_HELP_SET Options disponibles: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Définit le propriétaire d'un canal +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Définit le successeur d'un canal +CHAN_HELP_CMD_SET_DESC DESC Définit la description du canal +CHAN_HELP_CMD_SET_URL URL Associe un site avec un canal +CHAN_HELP_CMD_SET_EMAIL EMAIL Associe un E-mail avec le canal +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Définit un message envoyé aux utilisateurs qui entrent sur le canal - TOPIC Change le topic du canal +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Définit comment les services mettent les bans sur le canal +CHAN_HELP_CMD_SET_MLOCK MLOCK Oblige ou interdit des modes de canal +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Maintient le topic quand le canal n'est pas utilisé +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Envoie une notice quand OP/DEOP sont utilisés +CHAN_HELP_CMD_SET_PEACE PEACE Régule l'utilisation de commandes sensibles +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Cacher le canal de la commande LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Restreindre l'accès au canal +CHAN_HELP_CMD_SET_SECURE SECURE Active les fonctions de sécurité de %S +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Contrôle plus strict du statut d'OP +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Contrôle plus strict du statut de propriétaire du canal +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Signe les kicks générés par la commande KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Le sujet peut uniquement être changé avec TOPIC +CHAN_HELP_CMD_SET_XOP XOP Change le système de privilèges utilisateurs +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Tapez %R%S HELP SET option pour plus d'informations sur une option particulière. CHAN_HELP_SET_FOUNDER - Syntaxe: SET canal FOUNDER pseudo + Syntaxe: %s canal FOUNDER pseudo Change le propriétaire d'un canal. Le nouveau pseudo doit être enregistré. CHAN_HELP_SET_SUCCESSOR - Syntaxe: SET canal SUCCESSOR pseudo + Syntaxe: %s canal SUCCESSOR pseudo Change le successeur d'un canal. Si le pseudo du propriétaire expire ou est effacé alors que le canal est toujours @@ -4402,13 +4506,13 @@ CHAN_HELP_SET_SUCCESSOR doit être enregistré. CHAN_HELP_SET_DESC - Syntaxe: SET canal DESC description + Syntaxe: %s canal DESC description Définit la description du canal, qui apparait dans les commandes LIST et INFO. CHAN_HELP_SET_URL - Syntaxe: SET canal URL [adresse] + Syntaxe: %s canal URL [adresse] Associe l'adresse de site web donnée avec le canal. Cette adresse sera affichée à chaque fois que quelqu'un demande des informations @@ -4416,7 +4520,7 @@ CHAN_HELP_SET_URL n'est donné, supprime l'adresse de site du canal. CHAN_HELP_SET_EMAIL - Syntaxe: SET canal EMAIL [adresse] + Syntaxe: %s canal EMAIL [adresse] Associe l'E-mail donné avec le canal. Cette E-mail sera affiché lorsque quelqu'un demande des informations @@ -4424,7 +4528,7 @@ CHAN_HELP_SET_EMAIL n'est donné, supprime l'E-mail actuel du canal. CHAN_HELP_SET_ENTRYMSG - Syntaxe: SET canal ENTRYMSG [message] + Syntaxe: %s canal ENTRYMSG [message] Définit le message qui sera envoyé en /notice aux utilisateurs quand ils entrent dans un canal. Si aucun @@ -4432,7 +4536,7 @@ CHAN_HELP_SET_ENTRYMSG l'entrée. CHAN_HELP_SET_BANTYPE - Syntaxe: SET canal BANTYPE typedeban + Syntaxe: %s canal BANTYPE typedeban Définit le type de ban qui sera utilisé par les services lorsqu'ils doivent bannir quelqu'un de votre canal. @@ -4445,7 +4549,7 @@ CHAN_HELP_SET_BANTYPE 3: ban de style *!*user@*.domain CHAN_HELP_SET_KEEPTOPIC - Syntaxe: SET canal KEEPTOPIC {ON | OFF} + Syntaxe: %s canal KEEPTOPIC {ON | OFF} Active ou désactive l'option de maintien du sujet pour un canal. Lorsque le maintien du sujet est défini, le @@ -4454,7 +4558,7 @@ CHAN_HELP_SET_KEEPTOPIC la prochaine fois que le canal sera créé. CHAN_HELP_SET_TOPICLOCK - Syntaxe: SET canal TOPICLOCK {ON | OFF} + Syntaxe: %s canal TOPICLOCK {ON | OFF} Active ou désactive l'option de verrouillage du sujet pour un canal. Lorsque le verrouillage du sujet est actif, @@ -4462,7 +4566,7 @@ CHAN_HELP_SET_TOPICLOCK avec la commande TOPIC. CHAN_HELP_SET_MLOCK - Syntaxe: SET canal MLOCK modes + Syntaxe: %s canal MLOCK modes Configure les modes maintenus sur le canal. %S vous permet de toujours garder certains modes, d'empêcher l'utilisation d'autres @@ -4499,7 +4603,7 @@ CHAN_HELP_SET_MLOCK pourront désormais être librement utilisés. CHAN_HELP_SET_PEACE - Syntaxe: SET canal PEACE {ON | OFF} + Syntaxe: %s canal PEACE {ON | OFF} Active ou désactive l'option de paix pour un canal. Quand elle est active, cette option empêche un @@ -4508,21 +4612,21 @@ CHAN_HELP_SET_PEACE égal au sien via les commandes de %S. CHAN_HELP_SET_PRIVATE - Syntaxe: SET canal PRIVATE {ON | OFF} + Syntaxe: %s canal PRIVATE {ON | OFF} Active ou désactive l'option private pour un canal. Si private est défini, un %R%S LIST ne comprendra le canal dans aucune liste. CHAN_HELP_SET_RESTRICTED - Syntaxe: SET canal RESTRICTED {ON | OFF} + Syntaxe: %s canal RESTRICTED {ON | OFF} Active ou désactive l'option d'accès restreint pour un canal. Quand l'accès restreint est activé, les utilisateurs qui ne sont pas inscrits à la liste d'accès seront kickés et bannis du canal. CHAN_HELP_SET_SECURE - Syntaxe: SET canal SECURE {ON | OFF} + Syntaxe: %s canal SECURE {ON | OFF} Active ou désactive les caractéristiques de sécurité %S pour un canal. Lorsque la sécurité est active, seuls les @@ -4531,14 +4635,14 @@ CHAN_HELP_SET_SECURE au canal, sous contrôle de la liste d'accès. CHAN_HELP_SET_SECUREOPS - Syntaxe: SET canal SECUREOPS {ON | OFF} + Syntaxe: %s canal SECUREOPS {ON | OFF} Active ou désactive le contrôle des OPs sur un canal. Lorsque le contrôle des OPs est actif, les utilisateurs qui ne sont pas sur la liste d'accès ne pourront être OP. CHAN_HELP_SET_SECUREFOUNDER - Syntaxe: SET canal SECUREFOUNDER {ON | OFF} + Syntaxe: %s canal SECUREFOUNDER {ON | OFF} Active ou désactive l'option contrôle du propriétaire pour un canal. Lorsque le contrôle du propriétaire est activé, seul le vrai @@ -4547,7 +4651,7 @@ CHAN_HELP_SET_SECUREFOUNDER avec %S. CHAN_HELP_SET_SIGNKICK - Syntaxe: SET canal SIGNKICK {ON | LEVEL | OFF} + Syntaxe: %s canal SIGNKICK {ON | LEVEL | OFF} Active ou désactive les kicks signés sur un canal. Quand cette option est utilisée, les kicks générés @@ -4560,7 +4664,7 @@ CHAN_HELP_SET_SIGNKICK pour plus d'informations. CHAN_HELP_SET_XOP - Syntaxe: SET canal XOP {ON | OFF} + Syntaxe: %s canal XOP {ON | OFF} Active ou désactive le système de listes de xOPs pour un canal. Si vous choisissez ce système, vous devez @@ -4585,7 +4689,7 @@ CHAN_HELP_SET_XOP d'accès ne pose aucun problème par contre. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4608,7 +4712,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Syntaxe: SET canal OPNOTICE {ON | OFF} + Syntaxe: %s canal OPNOTICE {ON | OFF} Active ou désactive l'option notice sur OP/DEOP pour un canal. Lorsque notice sur OP/DEOP est défini, %S enverra une notice au @@ -5174,14 +5278,6 @@ CHAN_SERVADMIN_HELP_DROP peuvent effacer un canal pour lequel ils n'ont pas été identifiés. -CHAN_SERVADMIN_HELP_SET - - Les Services operators peuvent aussi définir l'option - NOEXPIRE, avec lequel les canaux peuvent être empêchés - d'expirer. De plus, les Services operators peuvent définir - les options de tout canal sans s'identifier à l'aide du - mot de passe du canal. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Syntaxe: SET canal NOEXPIRE {ON | OFF} @@ -5526,8 +5622,8 @@ OPER_HELP_CMD_KILLCLONES certain nom d'hôte OPER_HELP_CMD_AKILL AKILL Contrôle la liste des AKILLs -OPER_HELP_CMD_SGLINE - SGLINE Contrôle la liste des SGLINEs +OPER_HELP_CMD_SNLINE + SNLINE Contrôle la liste des SNLINEs OPER_HELP_CMD_SQLINE SQLINE Contrôle la liste des SQLINEs OPER_HELP_CMD_SZLINE @@ -5743,52 +5839,52 @@ OPER_HELP_AKILL Réservé aux opérateurs des Services. -OPER_HELP_SGLINE - Syntaxe: SGLINE ADD [+échéance] masque:raison - SGLINE DEL {masque | numéro d'entrée | liste} - SGLINE LIST [masque | liste] - SGLINE VIEW [masque | liste] - SGLINE CLEAR +OPER_HELP_SNLINE + Syntaxe: SNLINE ADD [+échéance] masque:raison + SNLINE DEL {masque | numéro d'entrée | liste} + SNLINE LIST [masque | liste] + SNLINE VIEW [masque | liste] + SNLINE CLEAR Permet aux OPérateurs des Services de manipuler la liste - de SGLINEs. Si un utilisateur ayant un vrai nom correspondant - à un masque de SGLINE tente de se connecter, les Services ne + de SNLINEs. Si un utilisateur ayant un vrai nom correspondant + à un masque de SNLINE tente de se connecter, les Services ne lui permettront pas de continuer sa session IRC. - SGLINE ADD ajoute le masque de vrai nom donné à la liste - de SGLINEs pour la raison précisée (qui doit être donnée). + SNLINE ADD ajoute le masque de vrai nom donné à la liste + de SNLINEs pour la raison précisée (qui doit être donnée). échéance est un nombre entier suivi par un d (jours), h (heures), ou m (minutes). Les combinaisons (telles que 1h30m) ne sont pas permises. Si l'unité n'est pas incluse, la valeur est en jours par défaut (donc +30 est équivalent - à 30 jours). Pour ajouter une SGLINE qui n'expire pas, utilisez + à 30 jours). Pour ajouter une SNLINE qui n'expire pas, utilisez +0. Si le masque de vrai nom à ajouter commence par un +, une échéance doit être donnée, même si c'est la même que - celle par défaut. L'échéance par défaut pour les SGLINEs peut + celle par défaut. L'échéance par défaut pour les SNLINEs peut être consultée par la commande STATS AKILL. Note: puisque le masque de vrai nom peut contenir des espaces, le séparateur entre lui et la raison est le signe deux points. - La commande SGLINE DEL supprime le masque donné de la liste - de SGLINEs s'il existe. Si une liste de numéros d'entrées + La commande SNLINE DEL supprime le masque donné de la liste + de SNLINEs s'il existe. Si une liste de numéros d'entrées est donnée, ces entrées sont supprimées. (Voyez l'exemple pour LIST ci-dessous.) - La commande SGLINE LIST affiche la liste des SGLINEs. Si un + La commande SNLINE LIST affiche la liste des SNLINEs. Si un masque joker est donné, seules les entrées correspondantes au masque sont affichées. Si une liste de numéros d'entrées est donnée, seules ces entrées sont affichées, par exemple: - SGLINE LIST 2-5,7-9 - Liste les entrées de la liste de SGLINEs numéro 2 à 5 + SNLINE LIST 2-5,7-9 + Liste les entrées de la liste de SNLINEs numéro 2 à 5 et 7 à 9. - SGLINE VIEW est une version plus détaillée de SGLINE LIST, - et affichera par qui et quand a été ajoutée une SGLINE et + SNLINE VIEW est une version plus détaillée de SNLINE LIST, + et affichera par qui et quand a été ajoutée une SNLINE et sa date d'expiration, en plus du masque de vrai nom et de la raison. - SGLINE CLEAR vide toutes les entrées de la liste de SGLINEs. + SNLINE CLEAR vide toutes les entrées de la liste de SNLINEs. Réservé aux OPérateurs des Services. @@ -371,6 +371,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Åßóáé ôþñá ìÝóá óôçí ïìÜäá ôïõ %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY ^_êùäéêü^_ @@ -805,9 +813,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d øåõäþíõìá ìÝóá óôçí ïìÜäá. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -857,18 +865,15 @@ NICK_SENDPASS_UNAVAILABLE Ç SENDPASS åíôïëÞ äåí åßíáé äéáèÝóéìç ãéáôß ÷ñçóéìïðïéåßôáé ç êùäéêïðïßçóç. NICK_SENDPASS_SUBJECT Ï êùäéêüò ôïõ øåõäþíõìïõ (%s) -NICK_SENDPASS_HEAD - ÃåéÜ, -NICK_SENDPASS_LINE_1 - Åßóáé óôçí ëßóôá ãéá íá ëÜâåéò ôïí êùäéêü ôïõ øåõäþíõìïý óïõ %s ìÝóù e-mail. -NICK_SENDPASS_LINE_2 - Ï êùäéêü óïõ åßíáé %s Ãéá ðåñéóóüôåñç áóöÜëåéá, èá ðñÝðåé íá áëëÜîåéò üóï óýíôïìá ãßíåôáé ôïí êùäéêü óïõ áöïý ëÜâåéò ôïí êùäéêü óïõ óå e-mail. -NICK_SENDPASS_LINE_3 - Áí äåí ãíùñßæåéò ãéáôß áõôü ôï e-mail óôÜëèçêå óå óÝíá, ðáñáêáëþ áãíüçóÝ ôï ÷ùñßò åñùôÞóåéò êëð. -NICK_SENDPASS_LINE_4 - ÐÁÑÁÊÁËÙ ÌÇÍ ÁÐÁÍÔÇÓÅÉÓ ÓÅ ÁÕÔÏ ÔÏ E-MAIL! -NICK_SENDPASS_LINE_5 - %s åðéêåöáëåßò õðçñåóéþí. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Ï êùäéêüò ôïõ %s Ý÷åé óôáëèåß. @@ -882,10 +887,9 @@ NICK_RESETPASS_MESSAGE You have requested to have the pasword for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - - PLEASE DON'T ANSWER TO THIS MAIL! - + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_RESETPASS_COMPLETE Password reset email for %s has been sent. @@ -935,17 +939,14 @@ NICK_ENTER_REG_CODE A passcode has been sent to %s, please type %R%s confirm <passcode> to complete registration NICK_REG_MAIL_SUBJECT Nickname Registration (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - You have requested to register the following nickname %s. -NICK_REG_MAIL_LINE_2 + + You have requested to register the nickname %s on %s. Please type " %R%s confirm %s " to complete registration. -NICK_REG_MAIL_LINE_3 - If you don't know why this mail is sent to you, please ignore it silently. -NICK_REG_MAIL_LINE_4 - PLEASE DON'T ANSWER TO THIS MAIL! -NICK_REG_MAIL_LINE_5 + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_GETPASS_PASSCODE_IS Passcode for %s is %s. @@ -1047,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1096,6 +1099,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Ôï êáíÜëé %s äéáãñÜöôçêå áðü ôéò õðçñåóßåò. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET channel option parameters @@ -2034,12 +2065,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT New memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 + You've just received a new memo from %s. This is memo number %d. -MEMO_MAIL_TEXT3 - Memo Text: + + Memo text: + + %s ########################################################################### # @@ -2573,22 +2606,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Åîáñ÷Þò ÷ñüíïò ëÞîçò AKILL: 1 ëåðôü OPER_STATS_AKILL_EXPIRE_NONE Åîáñ÷Þò ÷ñüíïò ëÞîçò AKILL: Äåí ëÞãåé ðïôÝ -OPER_STATS_SGLINE_COUNT - Ùò ôþñá õðÜñ÷ïõí SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: %d ìÝñåò -OPER_STATS_SGLINE_EXPIRE_DAY - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: 1 ìÝñá -OPER_STATS_SGLINE_EXPIRE_HOURS - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: %d þñåò -OPER_STATS_SGLINE_EXPIRE_HOUR - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: 1 þñá -OPER_STATS_SGLINE_EXPIRE_MINS - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: %d ëåðôÜ -OPER_STATS_SGLINE_EXPIRE_MIN - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: 1 ëåðôü -OPER_STATS_SGLINE_EXPIRE_NONE - Åîáñ÷Þò ÷ñüíïò ëÞîçò SGLINE: Äåí ëÞãåé ðïôÝ +OPER_STATS_SNLINE_COUNT + Ùò ôþñá õðÜñ÷ïõí SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: %d ìÝñåò +OPER_STATS_SNLINE_EXPIRE_DAY + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: 1 ìÝñá +OPER_STATS_SNLINE_EXPIRE_HOURS + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: %d þñåò +OPER_STATS_SNLINE_EXPIRE_HOUR + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: 1 þñá +OPER_STATS_SNLINE_EXPIRE_MINS + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: %d ëåðôÜ +OPER_STATS_SNLINE_EXPIRE_MIN + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: 1 ëåðôü +OPER_STATS_SNLINE_EXPIRE_NONE + Åîáñ÷Þò ÷ñüíïò ëÞîçò SNLINE: Äåí ëÞãåé ðïôÝ OPER_STATS_SQLINE_COUNT Ùò ôþñá õðÜñ÷ïõí SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2716,49 +2749,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR Ç ëßóôá AKILL êáèáñßóôçêå. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiry] {mask | entry-list}[:reason]] -OPER_SGLINE_UNSUPPORTED - Óõãíþìç, ç åíôïëÞ SGLINE äåí åßíáé äéáèÝóéìç óå áõôü ôï äßêôõï. -OPER_SGLINE_EXISTS - %s õðÜñ÷åé Þäç óôçí ëßóôá SGLINE. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+expiry] {mask | entry-list}[:reason]] +OPER_SNLINE_UNSUPPORTED + Óõãíþìç, ç åíôïëÞ SNLINE äåí åßíáé äéáèÝóéìç óå áõôü ôï äßêôõï. +OPER_SNLINE_EXISTS + %s õðÜñ÷åé Þäç óôçí ëßóôá SNLINE. +OPER_SNLINE_ALREADY_COVERED %s Ý÷åé Þäç êáëõöèåß áðü ôïí %s. -OPER_SGLINE_REACHED_LIMIT - Óõãíþìç, ìðïñåßò íá Ý÷åéò ìüíï %d SGLINEs. -OPER_SGLINE_ADDED - %s ðñïóèÝèçêå óôçí ëßóôá SGLINE. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Óõãíþìç, ìðïñåßò íá Ý÷åéò ìüíï %d SNLINEs. +OPER_SNLINE_ADDED + %s ðñïóèÝèçêå óôçí ëßóôá SNLINE. +OPER_SNLINE_CHANGED Ôï ÷ñïíéêü üñéï ôïõ/ôçò %s Üëëáîå. -OPER_SGLINE_NOT_FOUND - %s äåí âñÝèçêå óôçí ëßóôá SGLINE. -OPER_SGLINE_NO_MATCH - Äåí âñÝèçêáí èÝóåéò óôçí ëßóôá SGLINE. -OPER_SGLINE_DELETED - %s äéáãñÜöçêå áðü ôçí ëßóôá SGLINE. -OPER_SGLINE_DELETED_ONE - ÄéáãñÜöçêå 1 èÝóç áðü ôçí ëßóôá SGLINE. -OPER_SGLINE_DELETED_SEVERAL - ÄéáãñÜöçêáí %d èÝóåéò áðü ôçí ëßóôá SGLINE. -OPER_SGLINE_LIST_EMPTY - Ç ëßóôá SGLINE åßíáé Üäåéá. -OPER_SGLINE_LIST_HEADER - Ç Ýùò ôþñá ëßóôá SGLINE åßíáé ïé åîçò: +OPER_SNLINE_NOT_FOUND + %s äåí âñÝèçêå óôçí ëßóôá SNLINE. +OPER_SNLINE_NO_MATCH + Äåí âñÝèçêáí èÝóåéò óôçí ëßóôá SNLINE. +OPER_SNLINE_DELETED + %s äéáãñÜöçêå áðü ôçí ëßóôá SNLINE. +OPER_SNLINE_DELETED_ONE + ÄéáãñÜöçêå 1 èÝóç áðü ôçí ëßóôá SNLINE. +OPER_SNLINE_DELETED_SEVERAL + ÄéáãñÜöçêáí %d èÝóåéò áðü ôçí ëßóôá SNLINE. +OPER_SNLINE_LIST_EMPTY + Ç ëßóôá SNLINE åßíáé Üäåéá. +OPER_SNLINE_LIST_HEADER + Ç Ýùò ôþñá ëßóôá SNLINE åßíáé ïé åîçò: Íïõ ÌÜóêá Ëüãïò -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Current SGLINE list: +OPER_SNLINE_VIEW_HEADER + Current SNLINE list: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (by %s on %s; %s) %s -OPER_SGLINE_CLEAR - Ç ëßóôá SGLINE êáèáñßóôçêå. +OPER_SNLINE_CLEAR + Ç ëßóôá SNLINE êáèáñßóôçêå. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3402,6 +3435,8 @@ NICK_HELP_CMD_REGISTER REGISTER Êáôï÷õñþíåé Ýíá øåõäþíõìï NICK_HELP_CMD_GROUP GROUP ÌðÝíåôå óå ïìÜäá øåõäþíõìïõ +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Óáò áíáãíùñßæåé ìå ôç ÷ñÞóç êùäéêïý NICK_HELP_CMD_ACCESS @@ -3538,7 +3573,16 @@ NICK_HELP_GROUP Óçìåßùóç: üëá ôá øåõäþíõìá ðïõ áíÞêïõí óôçí ßäéá ïìÜäá Ý÷ïõí ôïí ßäéï êùäéêü. - + +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Óýíôáîç: IDENTIFY êùäéêü @@ -3601,26 +3645,40 @@ NICK_HELP_ACCESS ACCESS LIST Åìöáíßæåé ôçí ôñÝ÷ïõóá ëßóôá ðñüóâáóçò. -NICK_HELP_SET +NICK_HELP_SET_HEAD Óýíôáîç: SET option parameters ÁëëÜæåé äéÜöïñåò åðéëïãÝò ôïõ øåõäùíýìïõ. Ç åðéëïãÞ ìðïñåß íá åßíáé: +NICK_HELP_CMD_SET_DISPLAY DISPLAY ÁëëÜæåé ôçí ëßóôá ôùí ïìÜäùí +NICK_HELP_CMD_SET_PASSWORD PASSWORD ÁëëÜæåé ôïí êùäéêü ôïõ øåõäùíýìïõ óáò +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE ÁëëÜæåé ôç ãëþóóá ðïõ ÷ñçóéìïðïéïýí ïé õðçñåóßåò üôáí ôéò ÷ñçóéìïðïéåßôå +NICK_HELP_CMD_SET_URL URL Óõó÷åôßæåé Ýíá URL ìå ôï øåõäþíõìü óáò +NICK_HELP_CMD_SET_EMAIL EMAIL Óõó÷åôßæåé ìßá äéåýèõíóç e-mail ìå ôï øåõäþíõìü óáò +NICK_HELP_CMD_SET_ICQ ICQ Óõó÷åôßæåé Ýíá íïýìåñï ICQ ìå ôï øåõäþíõìü óáò +NICK_HELP_CMD_SET_GREET GREET Óõó÷åôßæåé Ýíá ìÞíõìá ÷áéñåôéóìïý ìå ôï øåõäþíõìü óáò +NICK_HELP_CMD_SET_KILL KILL Åíåñãïðïéåß/áðåíåñãïðïéåß ôçí ðñïóôáóßá ìå áðïóýíäåóç +NICK_HELP_CMD_SET_SECURE SECURE Åíåñãïðïéåß/áðåíåñãïðïéåß ôç ëåéôïõñãßá áóöÜëåéáò +NICK_HELP_CMD_SET_PRIVATE PRIVATE Åìðïäßæåé ôï øåõäþíõìü óáò íá åìöáíßæåôáé ìå ôçí åíôïëÞ %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Áðïêñýðôåé óõãêåêñéìÝíá ôìÞìáôá ðëçñïöïñéþí ôïõ øåõäùíýìïõ +NICK_HELP_CMD_SET_MSG MSG ÁëëÜæåé ôçí ìÝèïäï åðéêïéíùíßáò ìå ôéò õðçñåóßåò +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Ãéá íá ÷ñçóéìïðïéÞóåôå áõôÞ ôçí åíôïëÞ, ðñÝðåé ðñþôá íá áíáãíùñéóôåßôå ìå ôïí êùäéêü óáò (ãéá ðåñéóóüôåñåò ðëçñïöïñßåò, @@ -3744,26 +3802,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -4082,11 +4154,11 @@ NICK_SERVADMIN_HELP_DROP Ìðïñåß íá óâÞóåéò êÜðïéï øåõäþíõìï ðïõ ìðïñåß íá åßíáé óôçí ïìÜäá óïõ ÷ùñßò íá Ý÷åéò îå÷ùñéóôÜ äéêáéþìáôá. Ôï óâÞóéìï ôïõ øåõäþíõìïõ Ý÷ïõí ôï äéêáßùìá íá ôï êÜíïõí ïé (åðéêåöáëåßò) Services Operators. - + NICK_SERVADMIN_HELP_INFO - Ïé Services Operators ìðïñïýí íá ÷ñçóéìïðïéïýí ôçí ALL ðáñÜìåôñï ãéá - êÜèå øåõäþíõìï. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Óýíôáîç: LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4200,6 +4272,8 @@ CHAN_HELP_CMD_REGISTER CHAN_HELP_CMD_SET SET Ñõèìßæåé ôéò åðéëïãÝò êáé ôéò ðëçñïöïñßåò ôïõ êáíáëéïý +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4302,7 +4376,15 @@ CHAN_HELP_DROP ÊÜíåé ôï êáíÜëé îåêáôï÷õñþóçìï,ôï áöÞíåé åëåýèåñï ÷ùñßò founder. Ãéá íá ãßíåé áõôü ðñÝðåé ï founder. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Óýíôáîç: SET êáíÜëé åðéëïãÞ ðáñÜìåôñïé ÅðéôñÝðïõí óôïí founder ôïõ êáíáëéïý íá åðéëÝîåé êáé íá ñõèìßóåé ôï êáíÜëé @@ -4310,40 +4392,63 @@ CHAN_HELP_SET ÄéáèÝóéìåò åðéëïãÝò: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER ÁëëÜæåé ôïí founder ôïõ êáíáëéïý +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR ÁëëÜæåé ôïí successor ôïõ êáíáëéïý +CHAN_HELP_CMD_SET_DESC DESC ÁëëÜæåé ôçí ðåñéãñáöÞ ôïõ êáíáëéïý +CHAN_HELP_CMD_SET_URL URL Óõó÷åôßæåé Ýíá URL ìå ôï êáíÜëé +CHAN_HELP_CMD_SET_EMAIL EMAIL Óõó÷åôßæåé Ýíá E-mail ìå ôï êáíÜëé +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG ÁëëÜæåé ôï ìÞíõìá åéóáãùãÞò ðïõ óôÝëíåôå óå üëïõò ôïõò ÷ñÞóôåò ðïõ ìðÝíïõí óôï êáíÜëé +CHAN_HELP_CMD_SET_BANTYPE BANTYPE ÁëëÜæåé ôïí ôýðï ôïõ ban ðïõ èá êÜíïõí ôá Services +CHAN_HELP_CMD_SET_MLOCK MLOCK Êëåßäùìá ôùí Modes ôïõ êáíáëéïý +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Íá áëëÜæåé ôï topic üôáí äåí ÷ñçóéìïðïéåßôáé ôï êáíÜëé +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Íá óôÝëíåé ìÝóá óôï êáíÜëé ìÞíõìá ðïéïò ÷ñçóéìïðïéåß OP/DEOP åíôïëÝò +CHAN_HELP_CMD_SET_PEACE PEACE Íá åëëáôþíåé ôçí ÷ñÞóç "âßáéùí" åíôïëþí +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Íá ìçí åìöáíßæåôáé ôï êáíÜëé üôáí ãßíåôáé åíôïëÞ LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Áðáãüñåõóç åéóüäïõ óôï êáíÜëé áí äåí Ý÷åéò access åêåß +CHAN_HELP_CMD_SET_SECURE SECURE Åíåñãïðïßçóç ôïõ %S ,ìåëëïíôéêÞ áóöÜëåéá +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Ìüíï üóïé Ý÷ïõí access èá Ý÷ïõí op +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER ÁóöÜëåéá ôïõ founder áðü ôï êáíÜëé +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Åìöáí. kicks ôá ïðïßá ãßíïíôáé ìå ôçí åíôïëÞ KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Ôï Topic ìðïñåß íá áëëÜîåé ìå ôçí åíôïëÞ TOPIC +CHAN_HELP_CMD_SET_XOP XOP Áí åßíáé ON äïõëåýåé ìå AOP/SOP,áí åßíáé off ìå access +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL ÃñÜøå %R%S HELP åðéëïãÞ ãéá ðåñéóóüôåñåò ðëçñïöïñßåò ãéá ôçí êÜèå åíôïëÞ. CHAN_HELP_SET_FOUNDER - Óýíôáîç: SET êáíÜëé FOUNDER øåõäþíõìï + Óýíôáîç: %s êáíÜëé FOUNDER øåõäþíõìï ÁëëÜæåé ôïí founder ôïõ êáíáëéïý. Ôï íÝï øåõäþíõìï ðñÝðåé íá åßíáé êáôï÷õñùìÝíï. CHAN_HELP_SET_SUCCESSOR - Óýíôáîç: SET êáíÜëé SUCCESSOR øåõäþíõìï + Óýíôáîç: %s êáíÜëé SUCCESSOR øåõäþíõìï ÁëëÜæåé ôïí successor ôïõ êáíáëéïý. Áí ôï øåõäþíõìï ôïõ founder ëÞîåé Þ óâçóôåß (drop) ôüôå ôï êáíÜëé èá åßíáé áêüìá êáôï÷õñùìÝíï. @@ -4353,13 +4458,13 @@ CHAN_HELP_SET_SUCCESSOR successor. Ôï íÝï øåõäþíõìï èá ðñÝðåé íá åßíáé êáôï÷õñùìÝíï. CHAN_HELP_SET_DESC - Óýíôáîç: SET êáíÜëé DESC ðåñéãñáöÞ + Óýíôáîç: %s êáíÜëé DESC ðåñéãñáöÞ ÁëëÜæåôå ôçí ðåñéãñáöÞ ôïõ êáíáëéïý, ç ïðïßá öÝíåôáé ìå ôçí åíôïëÞ LIST êáé INFO. CHAN_HELP_SET_URL - Óýíôáîç: SET êáíÜëé URL [url] + Óýíôáîç: %s êáíÜëé URL [url] Óõó÷åôßæåé Ýíá URL ìå ôï êáíÜëé. Áõôü ôï URL èá åìöáíßæåôáé üôáí êÜðïéïò èá êïéôÜæåéò ôéò ðëçñïöïñßåò ôïõ êáíáëéïý @@ -4367,7 +4472,7 @@ CHAN_HELP_SET_URL èá óâçóôåß ïðïéïäÞðïôå URL åß÷å äùèåß ðáëáéüôåñá óôï êáíÜëé. CHAN_HELP_SET_EMAIL - Óýíôáîç: SET êáíÜëé EMAIL [äéåýèõíóç] + Óýíôáîç: %s êáíÜëé EMAIL [äéåýèõíóç] Óõó÷åôßæåé ìéá äéåýèõíóç E-mail ìå ôï êáíÜëé. ÁõôÞ ç äéåýèõíóç åìöáíßæåôáé üôáí êÜðïéïò èÝëåé íá äåé @@ -4376,14 +4481,14 @@ CHAN_HELP_SET_EMAIL åß÷å äùèåß óôï êáíÜëé. CHAN_HELP_SET_ENTRYMSG - Óýíôáîç: SET êáíÜëé ENTRYMSG [ìÞíõìá] + Óýíôáîç: %s êáíÜëé ENTRYMSG [ìÞíõìá] ÁëëÜæåé ôï ìÞíõìá åéóáãùãÞò ôï ïðïßï óôÝëíåôå óå êÜèå ÷ñÞóôç ìÝóù /notice (ðáñáôÞñçóç) üôáí áõôüò ìðÝíåé óôï êáíÜëé. Áí äåí äùèåß êáìßá ðáñÜìåôñïò, äåí èá óôÝëíåôå êáíÝíá ìÞíõìá óôï ÷ñÞóôç,ï ïðïßïò èá åéóÝñ÷åôáé óôï êáíÜëé. CHAN_HELP_SET_BANTYPE - Óýíôáîç: SET êáíÜëé BANTYPE ôýðïò-ban + Óýíôáîç: %s êáíÜëé BANTYPE ôýðïò-ban ÁëëÜæåé ôïí ôýðï ôïõ ban, ï ïðïßïò èá ÷ñçóéìïðïéåßôáé áðü ôéò õðçñåóßåò üôáí èá ÷ñåéÜæåôáé íá êÜíåé êÜðïéïí ban áðü ôï êáíÜëé (ð÷ akick). @@ -4396,7 +4501,7 @@ CHAN_HELP_SET_BANTYPE 3: ôï ban èá åßíáé ôçò ìïñöÞò *!*user@*.domain CHAN_HELP_SET_KEEPTOPIC - Óýíôáîç: SET êáíÜëé KEEPTOPIC {ON | OFF} + Óýíôáîç: %s êáíÜëé KEEPTOPIC {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ topic retention ôïõ êáíáëéïý. ¼ôáí ôï topic retention åßíáé on, ôï topic ôïõ êáíáëéïý @@ -4404,14 +4509,14 @@ CHAN_HELP_SET_KEEPTOPIC ôï êáíÜëé, êáé èá áðïèçêåýåôáé ãéá ôçí åðüìåíç öïñÜ. CHAN_HELP_SET_TOPICLOCK - Óýíôáîç: SET êáíÜëé KEEPTOPIC {ON | OFF} + Óýíôáîç: %s êáíÜëé KEEPTOPIC {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ êëåßäùìá topic ôïõ êáíáëéïý. ¼ôáí ôï êëåßäùìá topic åßíáé on, ï %S äåí èá åðéôñÝðåé óå êáíÝíáí íá áëëÜîåé ôï topic ôïõ êáíáëéïý åêôüò ôçò åíôïëÞò TOPIC ôïõ. CHAN_HELP_SET_MLOCK - Óýíôáîç: SET êáíÜëé MLOCK modes + Óýíôáîç: %s êáíÜëé MLOCK modes Êáèïñßæåé ôï êëåßäùìá ôùí modes ãéá ôï êáíÜëé. Ï %S óáò åðéôñÝðåé íá êáèïñßóåôå óõãêåêñéìÝíá modes ãéá ôï êáíÜëé @@ -4448,7 +4553,7 @@ CHAN_HELP_SET_MLOCK áðåíåñãïðïéçèïýí. CHAN_HELP_SET_PEACE - Óýíôáîç: SET êáíÜëé PEACE {ON | OFF} + Óýíôáîç: %s êáíÜëé PEACE {ON | OFF} Åíåñãïðïéåß Þ áðååñãïðïéåß ôçí åíôïëÞ peace óôï êáíÜëé. ¼ôáí ç åíôïëÞ peace åßíáé on, ï ÷ñÞóôçò äåí ìðïñåß íá êÜíåé kick, @@ -4456,21 +4561,21 @@ CHAN_HELP_SET_PEACE level áðü áõôüí Þ ßóï ìå áõôüí ìÝóù åíôïëþí %S. CHAN_HELP_SET_PRIVATE - Óýíôáîç: SET êáíÜëé PRIVATE {ON | OFF} + Óýíôáîç: %s êáíÜëé PRIVATE {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ private ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ç private åíôïëÞ, ôï êáíÜëé äå óõìðåñéëáìâÜíåôáé óôç ëßóôá ðïõ ðñïêýðôåé áðü ôçí åíôïëÞ %R%S LIST. CHAN_HELP_SET_RESTRICTED - Óýíôáîç: SET êáíÜëé RESTRICTED {ON | OFF} + Óýíôáîç: %s êáíÜëé RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Óýíôáîç: SET êáíÜëé SECURE {ON | OFF} + Óýíôáîç: %s êáíÜëé SECURE {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôéò äõíáôüôçôåò áóöÜëåéáò ôïõ %S ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ôï SECURE, ìüíï ïé ÷ñÞóôåò ðïõ @@ -4479,14 +4584,14 @@ CHAN_HELP_SET_SECURE áðü ôç ëßóôá ðñüóâáóçò. CHAN_HELP_SET_SECUREOPS - Óýíôáîç: SET êáíÜëé SECUREOPS {ON | OFF} + Óýíôáîç: %s êáíÜëé SECUREOPS {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ ðñïóôáôåõìÝíçò äéá÷åßñçóçò ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ç ðñïóôáôåõìÝíç äéá÷åßñçóç, ïé ÷ñÞóôåò ðïõ äåí åßíáé óôç ëßóôá ðñüóâáóçò, äå ìðïñïýí íá ðÜñïõí op. CHAN_HELP_SET_SECUREFOUNDER - Óýíôáîç: SET êáíÜëé SECUREFOUNDER {ON | OFF} + Óýíôáîç: %s êáíÜëé SECUREFOUNDER {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ áóöáëÞò founder ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ç åðéëïãÞ áóöáëÞò founder, ìüíï ï ðñáãìáôéêüò founder @@ -4495,7 +4600,7 @@ CHAN_HELP_SET_SECUREFOUNDER áíáãíþñéóçò ìå ôïí %S. CHAN_HELP_SET_SIGNKICK - Óýíôáîç: SET êáíÜëé SIGNKICK {ON | LEVEL | OFF} + Óýíôáîç: %s êáíÜëé SIGNKICK {ON | LEVEL | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ signed kicks ôïõ êáíáëéïý. ¼ôáí åíåñãïðïéåßôáé ç åðéëïãÞ SIGNKICK, ôá kicks èá @@ -4507,7 +4612,7 @@ CHAN_HELP_SET_SIGNKICK kicks signed. Äåò %R%S HELP LEVELS ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. CHAN_HELP_SET_XOP - Óýíôáîç: SET êáíÜëé XOP {ON | OFF} + Óýíôáîç: %s êáíÜëé XOP {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ xOP system ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ç åðéëïãÞ XOP, ÷ñçóéìïðïéåßò ôéò @@ -4523,7 +4628,7 @@ CHAN_HELP_SET_XOP äåí èá õðÜñîåé êáíÝíá ðñüâëçìá. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4546,7 +4651,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Óýíôáîç: SET êáíÜëé OPNOTICE {ON | OFF} + Óýíôáîç: %s êáíÜëé OPNOTICE {ON | OFF} Åíåñãïðïéåß Þ áðåíåñãïðïéåß ôçí åðéëïãÞ åíçìÝñùóçò op ãéá Ýíá êáíÜëé. ¼ôáí åíåñãïðïéåßôáé ç åíçìÝñùóç op, ï %S óôÝëíåé Ýíá notice óôïõò ops @@ -5090,13 +5195,6 @@ CHAN_SERVADMIN_HELP_DROP ìðïñïõí íá ôï êÜíïõí áõôü óå Ýíá êáíÜëé, ÷ùñßò íá êÜíïõí åíôïëÞ áíáãíþñéóçò ãéá ôï êáíÜëé. -CHAN_SERVADMIN_HELP_SET - - Ïé Services Operators ìðïñïýí íá åðéëÝîïõí ôçí NOEXPIRE åíôïëÞ, óå - áõôÜ ðïõ äåí èÝëïõí ðïôÝ íá ëÞîïõí. - Åðßóçò, ïé Services Operators ìðïñïýí íá áëëÜîïõí ôéò åðéëïãÝò ãéá êÜèå êáíÜëé - ÷ùñßò íá êÜíïõí åíôïëÞ áíáãíþñéóçò óå êÜèå êáíÜëé. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Óýíôáîç: SET êáíÜëé NOEXPIRE {ON | OFF} @@ -5440,8 +5538,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Óêïôþíåé üëïõò ôïõò ÷ñÞóôåò ðïõ Ý÷ïõí ôï ßäéï host OPER_HELP_CMD_AKILL AKILL ÐñïóèÝôåé ip êëð óôçí ëßóôá AKILL -OPER_HELP_CMD_SGLINE - SGLINE ÐñïóèÝôåé ip óôçí ëßóôá SGLINE +OPER_HELP_CMD_SNLINE + SNLINE ÐñïóèÝôåé ip óôçí ëßóôá SNLINE OPER_HELP_CMD_SQLINE SQLINE ÐñïóèÝôåé ip óôçí ëßóôá SQLINE OPER_HELP_CMD_SZLINE @@ -5642,50 +5740,50 @@ OPER_HELP_AKILL Ìüíï ãéá ôïõò Services operators. -OPER_HELP_SGLINE - Óýíôáîç: SGLINE ADD [+expiry] ìÜóêá:ëüãïò - SGLINE DEL {ìÜóêá | èÝóåéò-íïýìåñá | ëßóôá} - SGLINE LIST [ìÜóêá | ëßóôá] - SGLINE VIEW [ìÜóêá | ëßóôá] - SGLINE CLEAR - - Ïé Services operators ìðïñïýí íá áëëÜîïõí ôçí ëßóôá SGLINE. Áí - ï ÷ñÞóôçò ìå ôï ðñáãìáôéêü üíïìá ôáéñéÜæåé ìå ôçí SGLINE ìÜóêá,ôá +OPER_HELP_SNLINE + Óýíôáîç: SNLINE ADD [+expiry] ìÜóêá:ëüãïò + SNLINE DEL {ìÜóêá | èÝóåéò-íïýìåñá | ëßóôá} + SNLINE LIST [ìÜóêá | ëßóôá] + SNLINE VIEW [ìÜóêá | ëßóôá] + SNLINE CLEAR + + Ïé Services operators ìðïñïýí íá áëëÜîïõí ôçí ëßóôá SNLINE. Áí + ï ÷ñÞóôçò ìå ôï ðñáãìáôéêü üíïìá ôáéñéÜæåé ìå ôçí SNLINE ìÜóêá,ôá Services äåí èá ôïí áöÞóïõí íá óõíäåèåß. - Ç åíôïëÞ SGLINE ADD ðñïóèÝôåé ìéá ðñáãìáôéêÞ ìÜóêá óôçí ëßóôá SGLINE + Ç åíôïëÞ SNLINE ADD ðñïóèÝôåé ìéá ðñáãìáôéêÞ ìÜóêá óôçí ëßóôá SNLINE ìå êÜðïéïí ëüãï ôïí ïðïßï ðñÝðåé íá ôïí äþóåôå. Ôï expiry åßíáé óõãêåêñéìÝíï êáé åðéëÝãåôáé áðü ôá åðüìåíá, d (ìÝñåò), h (þñåò), Þ m (ëåðôÜ). Óõíäéáóìïß (üðùò 1h30m) äåí åðéôñÝðïíôáé . Áí äåí äþóåôå ôï ÷ñüíï áðü default èá åßíáé óå ìÝñåò (èá åßíáé +30 ðïõ óçìáßíåé 30 - ìÝñåò). Ãéá íá ðñïóèÝóåôå Ýíá SGLINE ðïõ íá ìçí ëÞãåé, ÷ñçóéìïðïéåßóôå +0. + ìÝñåò). Ãéá íá ðñïóèÝóåôå Ýíá SNLINE ðïõ íá ìçí ëÞãåé, ÷ñçóéìïðïéåßóôå +0. usermask îåêéíÜåé ìå +, ï ÷ñüíïò ëÞîçò èá ðñÝðåé íá äßíåôå áêüìá êáé áí åßíáé ßäéïò ìå ôïí default. Ï - óõãêåêñéìÝíïò ÷ñüíïò ëÞîçò ôçò åíôïëÞò SGLINE ìðïñåß íá âñåèåß ìå ôçí åíôïëÞ + óõãêåêñéìÝíïò ÷ñüíïò ëÞîçò ôçò åíôïëÞò SNLINE ìðïñåß íá âñåèåß ìå ôçí åíôïëÞ STATS AKILL. Óçìåßùóç: åðåéäÞ ôï ðñáãìáôéêü üíïìá-ìÜóêá ìðïñåß íá ðåñéÝ÷åé êåíÜ, äéá÷ùñéóôéêÜ ìåôáîý ôïõò íá åßóôå ðñïóåêôéêïß óôï ëüãï. - Ç åíôïëÞ SGLINE DEL áöáéñåß ìßá ìÜóêá áðü ôçí ëßóôá - SGLINE list áí õðÜñ÷åé. Áí ç ëßóôá ìå ôéò èÝóåéò-íïýìåñá äßíåôå, + Ç åíôïëÞ SNLINE DEL áöáéñåß ìßá ìÜóêá áðü ôçí ëßóôá + SNLINE list áí õðÜñ÷åé. Áí ç ëßóôá ìå ôéò èÝóåéò-íïýìåñá äßíåôå, áõôÝò äéáãñÜöïíôáé. (ÄÝò ôï ðáñÜäåéãìá LIST.) - Ç åíôïëÞ SGLINE LIST åìöáíßæåé ôçí ëßóôá ìå ôá SGLINE. + Ç åíôïëÞ SNLINE LIST åìöáíßæåé ôçí ëßóôá ìå ôá SNLINE. Áí äßíåôáé ìéá óõãêåêñéìÝíç ìÜóêá, èá åìöáíéóôïýí ïé èÝóåéò ðïõ áíôéóôïé÷ïýí óå áõôÞ ôç ìÜóêá Áí äßíåôå ç ëßóôá ìå ôéò èÝóåéò-íïýìåñá ìðïñåßôå íá ôéò äåßôå êáé áëëéþò, ðáñÜäåéãìá: - SGLINE LIST 2-5,7-9 + SNLINE LIST 2-5,7-9 Åìöáíßæåé ôéò èÝóåéò ìå ôá íïýìåñá 2 åùò 5 êáé 7 - åùò 9 ôçò ëßóôáò SGLINE. + åùò 9 ôçò ëßóôáò SNLINE. - Ç åíôïëÞ SGLINE VIEW åßíáé ðéï âåëôéùìÝíç áðü ôçí SGLINE LIST, êáé - åìöáíßæåé ðïéïò Ýâáëå ôï êÜèå SGLINE, ôçí çìåñïìçíßá ðïõ ìðÞêå, êáé ðüôå + Ç åíôïëÞ SNLINE VIEW åßíáé ðéï âåëôéùìÝíç áðü ôçí SNLINE LIST, êáé + åìöáíßæåé ðïéïò Ýâáëå ôï êÜèå SNLINE, ôçí çìåñïìçíßá ðïõ ìðÞêå, êáé ðüôå ëÞãåé, êáé öõóéêÜ ôç realname ìÜóêá êáé ôïí ëüãï. - Ç åíôïëÞ SGLINE CLEAR êáèáñßæåé üëåò ôéò èÝóåéò áðü ôçí ëßóôá SGLINE. + Ç åíôïëÞ SNLINE CLEAR êáèáñßæåé üëåò ôéò èÝóåéò áðü ôçí ëßóôá SNLINE. Ìüíï ãéá ôïõò Services operators. diff --git a/lang/hun.l b/lang/hun.l index 2a2bf0ea8..daad32421 100644 --- a/lang/hun.l +++ b/lang/hun.l @@ -377,6 +377,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Mostantól tagja vagy a %scsoportnak. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY válaszok NICK_IDENTIFY_SYNTAX IDENTIFY jelszó @@ -802,9 +810,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicknév van a csoportban. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER válaszok NICK_RECOVER_SYNTAX @@ -854,18 +862,15 @@ NICK_SENDPASS_UNAVAILABLE SENDPASS nem elérhetõ, amíg az encryption használatban van. NICK_SENDPASS_SUBJECT Nicknév jelszó (%s) -NICK_SENDPASS_HEAD +NICK_SENDPASS Hi, -NICK_SENDPASS_LINE_1 - Azt kérted, hogy a %s nicknév jelszavát küldjük el e-mailben. -NICK_SENDPASS_LINE_2 - A jelszavad %s Ezt a biztosnág miatt meg kell váltóztatni, miután megkaptad ezt a levelet. -NICK_SENDPASS_LINE_3 - Ha nem tudod miért kaptad ezt a levelet, akkor kérlek hagyd figyelmen kivül! -NICK_SENDPASS_LINE_4 - ERRE A LEVÉLRE NE VÁLASZOLJ!!! -NICK_SENDPASS_LINE_5 - %s adminisztrátorok. + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK %s nick jelszava elküldve. @@ -879,9 +884,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -926,18 +930,15 @@ NICK_ENTER_REG_CODE A kód a %s címre lett küldve, írd be %R%s confirm <kód> a regisztráció befejezéséhez. NICK_REG_MAIL_SUBJECT Nicknév Regisztráció (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - Te kérelmeztad a %s nick regisztrálását. -NICK_REG_MAIL_LINE_2 - Írd be: " %R%s confirm %s ", hogy befejezd a regisztrációt. -NICK_REG_MAIL_LINE_3 - Ha nem tudod miért kaptad a levelet, kérlek hagyd figyelmen kívül! -NICK_REG_MAIL_LINE_4 - NE VÁLASZOLJ A LEVÉLRE! -NICK_REG_MAIL_LINE_5 - %s adminisztrátorok. + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Kód a %s nickhez: %s. NICK_FORCE_REG @@ -1038,6 +1039,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatikus válaszok CHAN_IS_REGISTERED @@ -1087,6 +1090,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED %s csatorna regisztrációjának törlése sikerült. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET válaszok CHAN_SET_SYNTAX SET #szoba opció paraméterek @@ -2019,12 +2050,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail válaszok MEMO_MAIL_SUBJECT Új memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 - Kaptál egy új memo üzenetet %s nicktõl. Ez a memo a %d sorszámú. -MEMO_MAIL_TEXT3 - Memo Szöveg: + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s # RSEND válaszok MEMO_RSEND_PLEASE_WAIT @@ -2535,22 +2568,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Alap AKILL lejárati idõ: 1 perc OPER_STATS_AKILL_EXPIRE_NONE Alap AKILL lejárati idõ: Nem elévülõ -OPER_STATS_SGLINE_COUNT - Aktuális SGLINEok száma: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Alap SGLINE lejárati idõ: %d nap -OPER_STATS_SGLINE_EXPIRE_DAY - Alap SGLINE lejárati idõ: 1 nap -OPER_STATS_SGLINE_EXPIRE_HOURS - Alap SGLINE lejárati idõ: %d óra -OPER_STATS_SGLINE_EXPIRE_HOUR - Alap SGLINE lejárati idõ: 1 óra -OPER_STATS_SGLINE_EXPIRE_MINS - Alap SGLINE lejárati idõ: %d perc -OPER_STATS_SGLINE_EXPIRE_MIN - Alap SGLINE lejárati idõ: 1 perc -OPER_STATS_SGLINE_EXPIRE_NONE - Alap SGLINE lejárati ido: Nem elévülõ +OPER_STATS_SNLINE_COUNT + Aktuális SNLINEok száma: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Alap SNLINE lejárati idõ: %d nap +OPER_STATS_SNLINE_EXPIRE_DAY + Alap SNLINE lejárati idõ: 1 nap +OPER_STATS_SNLINE_EXPIRE_HOURS + Alap SNLINE lejárati idõ: %d óra +OPER_STATS_SNLINE_EXPIRE_HOUR + Alap SNLINE lejárati idõ: 1 óra +OPER_STATS_SNLINE_EXPIRE_MINS + Alap SNLINE lejárati idõ: %d perc +OPER_STATS_SNLINE_EXPIRE_MIN + Alap SNLINE lejárati idõ: 1 perc +OPER_STATS_SNLINE_EXPIRE_NONE + Alap SNLINE lejárati ido: Nem elévülõ OPER_STATS_SQLINE_COUNT Aktuális SQLINEok száma : %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2676,46 +2709,46 @@ OPER_AKILL_CLEAR OPER_CHANKILL_SYNTAX CHANKILL [+lejárat] {#szoba} [indok] -# SGLINE válaszok -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[ +lejárat] {maszk| sorszám }[:Indok]] -OPER_SGLINE_UNSUPPORTED - SGLINE nem használható ezen a hálózaton. -OPER_SGLINE_EXISTS - %s már szerepel az SGLINE listán. -OPER_SGLINE_ALREADY_COVERED +# SNLINE válaszok +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[ +lejárat] {maszk| sorszám }[:Indok]] +OPER_SNLINE_UNSUPPORTED + SNLINE nem használható ezen a hálózaton. +OPER_SNLINE_EXISTS + %s már szerepel az SNLINE listán. +OPER_SNLINE_ALREADY_COVERED %s társítva van %s által. -OPER_SGLINE_REACHED_LIMIT - Te csak %d számú SGLINE-t jegyezhetsz. -OPER_SGLINE_ADDED - %s hozzáadva a SGLINE listához. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Te csak %d számú SNLINE-t jegyezhetsz. +OPER_SNLINE_ADDED + %s hozzáadva a SNLINE listához. +OPER_SNLINE_CHANGED Lejárati idõ megváltozott: %s . -OPER_SGLINE_NOT_FOUND - %s nincs a SGLINE listán. -OPER_SGLINE_NO_MATCH - Nincs ilyen bejegyzés az SGLINE listán. -OPER_SGLINE_DELETED - %s törölve az SGLINE listáról. -OPER_SGLINE_DELETED_ONE - Törölve 1 bejegyzés a SGLINE listáról. -OPER_SGLINE_DELETED_SEVERAL - Törölve %d bejegyzés a SGLINE listáról. -OPER_SGLINE_LIST_EMPTY - SGLINE lista üres. -OPER_SGLINE_LIST_HEADER - Aktuális SGLINE lista: +OPER_SNLINE_NOT_FOUND + %s nincs a SNLINE listán. +OPER_SNLINE_NO_MATCH + Nincs ilyen bejegyzés az SNLINE listán. +OPER_SNLINE_DELETED + %s törölve az SNLINE listáról. +OPER_SNLINE_DELETED_ONE + Törölve 1 bejegyzés a SNLINE listáról. +OPER_SNLINE_DELETED_SEVERAL + Törölve %d bejegyzés a SNLINE listáról. +OPER_SNLINE_LIST_EMPTY + SNLINE lista üres. +OPER_SNLINE_LIST_HEADER + Aktuális SNLINE lista: Szám Maszk Indok -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Aktuális SGLINE lista: +OPER_SNLINE_VIEW_HEADER + Aktuális SNLINE lista: # szám, mask, set-by, set-idõ, lejárat, indok -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (%s által, ekkor: %s; %s) %s -OPER_SGLINE_CLEAR - Az SGLINE lista törölve. +OPER_SNLINE_CLEAR + Az SNLINE lista törölve. # SQLINE válaszok OPER_SQLINE_SYNTAX @@ -3336,6 +3369,8 @@ NICK_HELP_CMD_REGISTER REGISTER Nicknév regisztráció NICK_HELP_CMD_GROUP GROUP Csatlakozás egy csoporthoz +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Jelszavas azonosítás NICK_HELP_CMD_ACCESS @@ -3474,6 +3509,15 @@ NICK_HELP_IDENTIFY nicknek. Jelszónak ugyanannak kell lennie amit a regisztrációnál megadtál, vagy amire módosítottad. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_UPDATE Syntax: UPDATE @@ -3526,24 +3570,38 @@ NICK_HELP_ACCESS ACCESS LIST Megmutatja a hozzáférési listát. -NICK_HELP_SET +NICK_HELP_SET_HEAD Syntax: SET opció paraméterek Beállítható nicknév opciók. Az opció ezek egyike lehet: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Set the display of your group in Services +NICK_HELP_CMD_SET_PASSWORD PASSWORD Set your nickname password +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE A szervíz nyelvezetének megválasztása +NICK_HELP_CMD_SET_URL URL Egy URL társítása a nicknevedhez +NICK_HELP_CMD_SET_EMAIL EMAIL Egy E-mail cím társítása a nicknevedhez +NICK_HELP_CMD_SET_ICQ ICQ ICQ szám társítása a nicknevedhez +NICK_HELP_CMD_SET_GREET GREET Köszöntõ üzenet társítása a nicknevedhez +NICK_HELP_CMD_SET_KILL KILL A kill védelem be-,kikapcsolása +NICK_HELP_CMD_SET_SECURE SECURE A nickneved védelmének be-,kikapcsolása +NICK_HELP_CMD_SET_PRIVATE PRIVATE A nickneved %R%S LIST -ból való elrejtése +NICK_HELP_CMD_SET_HIDE HIDE A nicknévhez tartozó információk elrejtése +NICK_HELP_CMD_SET_MSG MSG Megváltoztatja a szervízzel való kommunikációt +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Ezen parancs kiadása elõtt, azonositanod kell magad, mint a nick tulajdonosa az IDENTIFY parancsot használva, írd @@ -3662,26 +3720,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -3993,10 +4065,11 @@ NICK_SERVADMIN_HELP_DROP különleges kiváltsága. Használat korlátozva Szervíz adminoknak. - + NICK_SERVADMIN_HELP_INFO - Szervíz adminok használhatják az ALL paramétert. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Syntax: LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] @@ -4122,6 +4195,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Szoba regisztrálása CHAN_HELP_CMD_SET SET Beállíthatod a csatornád opcióit +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4224,7 +4299,15 @@ CHAN_HELP_DROP Törli a megnevezett szoba regisztrációját. Csak a szoba founder használhatja. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Syntax: SET #szoba opció paraméterek Lehetõséget ad a foundernek, hogy a beállításokat @@ -4232,39 +4315,60 @@ CHAN_HELP_SET Elérhetõ opciók: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER A founder megváltoztatása +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR A successor megadása - PASSWORD A founder jelszó változtatása +CHAN_HELP_CMD_SET_DESC DESC A szobameghatározás állítás +CHAN_HELP_CMD_SET_URL URL Egy URL társítása a szobához +CHAN_HELP_CMD_SET_EMAIL EMAIL Egy E-mail cím társítása a szobához +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG A szoba belépo üzenetének állítása +CHAN_HELP_CMD_SET_BANTYPE BANTYPE A banolás tipusának beállítása +CHAN_HELP_CMD_SET_MLOCK MLOCK Szoba módok lezárása (+flag -flag) +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Topic megtartása ha a szoba nincs használatban +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Üzenetet küld az OP/VOICE parancsok használtáról +CHAN_HELP_CMD_SET_PEACE PEACE Szabályozza a kritikus parancsok használatát +CHAN_HELP_CMD_SET_PRIVATE PRIVATE A szoba elrejtése a listából +CHAN_HELP_CMD_SET_SECURE SECURE Aktiválja a %S biztonsági lehetõségeit +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS A csatornán az op státusz szigorú kezelése +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Csatornán a founder státusz szigorú kezelése +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Sign kickek, melyek a KICK paranccsal történnek +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Témaváltás letiltása +CHAN_HELP_CMD_SET_XOP XOP Xop (Sop, Aop, Hop, Vop) lista rendszer bekapcsolása +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Írd be: %R%S HELP SET opció bõvebb információért az adott opcióról. CHAN_HELP_SET_FOUNDER - Syntax: SET #szoba FOUNDER nick + Syntax: %s #szoba FOUNDER nick Megváltoztatja a szoba founderjét. Az új nicknév regisztrált kell hogy legyen! CHAN_HELP_SET_SUCCESSOR - Syntax: SET #szoba SUCCESSOR nick + Syntax: %s #szoba SUCCESSOR nick Megváltoztatja a successort a csatornán. Ha a founder neve elévül vagy törlõdik, de a szoba még regisztrált, akkor @@ -4275,20 +4379,20 @@ CHAN_HELP_SET_SUCCESSOR A nicknek regisztrálnak kell lennie. CHAN_HELP_SET_DESC - Syntax: SET #szoba DESC leírás + Syntax: %s #szoba DESC leírás Beállítható a szoba általános meghatározása, ami látszódni fog a LIST és INFO parancs használata esetén. CHAN_HELP_SET_URL - Syntax: SET #szoba URL [url] + Syntax: %s #szoba URL [url] Egy URL társítása a szobához. Ha van honlapja a szobának, akkor bárki megtudhatja, ha lekérte a szobáról az INFO-t. Ha nincs megadva paraméter, akkor törli a meglévõ URL-t. CHAN_HELP_SET_EMAIL - Syntax: SET #szoba EMAIL [emailcím] + Syntax: %s #szoba EMAIL [emailcím] Egy E-mail cím társítása a szobához. Ha van E-mail címe a szobának; akkor azt bárki megtudhatja, ha lekérte @@ -4296,14 +4400,14 @@ CHAN_HELP_SET_EMAIL törli a meglévõ e-mail címet. CHAN_HELP_SET_ENTRYMSG - Syntax: SET #szoba ENTRYMSG [üzenet] + Syntax: %s #szoba ENTRYMSG [üzenet] Beállít egy üzenetet, amit /notice formában fognak a szobába belépõ userek megkapni. Ha nincs paraméter megadva akkor a szoba belépõ üzenete törlõdik. CHAN_HELP_SET_BANTYPE - Syntax: SET #szoba BANTYPE bantípus + Syntax: %s #szoba BANTYPE bantípus A banolás típusának beállítása, amit a Services akkor fog használni, ha valakit banolni kell a csatornáról. @@ -4316,7 +4420,7 @@ CHAN_HELP_SET_BANTYPE 3: *!*user@*.domain formátumú tiltás CHAN_HELP_SET_KEEPTOPIC - Syntax: SET #szoba KEEPTOPIC {ON | OFF} + Syntax: %s #szoba KEEPTOPIC {ON | OFF} Engedélyezi vagy letiltja a topic megtartása opciót a szoba részére. Ha a topic megtartása be van állítva, @@ -4324,7 +4428,7 @@ CHAN_HELP_SET_KEEPTOPIC szobát, és visszaállítja a következõ megnyitáskor. CHAN_HELP_SET_TOPICLOCK - Syntax: SET #szoba TOPICLOCK {ON | OFF} + Syntax: %s #szoba TOPICLOCK {ON | OFF} Engedélyezi vagy letiltja a topic lezárása opciót a csatornán. Ha a topic lezárása be van kapcsolva,a %S nem @@ -4332,7 +4436,7 @@ CHAN_HELP_SET_TOPICLOCK paranccsal. CHAN_HELP_SET_MLOCK - Syntax: SET #szoba MLOCK módok + Syntax: %s #szoba MLOCK módok Beállíthatod a mode-lock opciót a csatornán. A %S lehetõséget nyújt arra, hogy meghatározd azokat a módokat @@ -4366,7 +4470,7 @@ CHAN_HELP_SET_MLOCK Minden mód szabadon ki/bekapcsolható. CHAN_HELP_SET_PEACE - Syntax: SET #szoba PEACE {ON | OFF} + Syntax: %s #szoba PEACE {ON | OFF} Engedélyezi vagy letiltja a peace opciót. Amikor a peace be van állítva, akkor a userek nem, @@ -4374,7 +4478,7 @@ CHAN_HELP_SET_PEACE egyenlõ vagy magasabb szintje van a %S parancsokhoz. CHAN_HELP_SET_PRIVATE - Syntax: SET #szoba PRIVATE {ON | OFF} + Syntax: %s #szoba PRIVATE {ON | OFF} Engedélyezi vagy letiltja a private opciót a csatornán. Amikor a private be van kapcsolva, a %R%S LIST @@ -4382,14 +4486,14 @@ CHAN_HELP_SET_PRIVATE a szoba. CHAN_HELP_SET_RESTRICTED - Syntax: SET #szoba RESTRICTED {ON | OFF} + Syntax: %s #szoba RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Syntax: SET #szoba SECURE {ON | OFF} + Syntax: %s #szoba SECURE {ON | OFF} Engedélyezi vagy letitlja a %S biztonsági lehetõségeit a szobában. Ha SECURE mûködik, csak azok a felhasználók @@ -4398,7 +4502,7 @@ CHAN_HELP_SET_SECURE a szobában jogokat, ha szerepelnek a hozzáférési listán. CHAN_HELP_SET_SECUREOPS - Syntax: SET #szoba SECUREOPS {ON | OFF} + Syntax: %s #szoba SECUREOPS {ON | OFF} Bekapcsolja vagy letiltja a secure ops opciót. Amikor a secure ops be van kapcsolva, akkor azok, akik @@ -4406,7 +4510,7 @@ CHAN_HELP_SET_SECUREOPS operátori státuszt. CHAN_HELP_SET_SECUREFOUNDER - Syntax: SET #szoba SECUREFOUNDER {ON | OFF} + Syntax: %s #szoba SECUREFOUNDER {ON | OFF} Engedélyezi vagy letiltja a secure founder opciót a csatornán. Amikor a secure founder be van állítva, csak @@ -4415,7 +4519,7 @@ CHAN_HELP_SET_SECUREFOUNDER akik csak az IDENTIFY parancsot használták a %S-ben. CHAN_HELP_SET_SIGNKICK - Syntax: SET #szoba SIGNKICK {ON | SZINT | OFF} + Syntax: %s #szoba SIGNKICK {ON | SZINT | OFF} Engedélyezi vagy letiltja a signed kick opciót a csatornán Amikor a SIGNKICK be van állítva, a %S KICK parancsával @@ -4427,7 +4531,7 @@ CHAN_HELP_SET_SIGNKICK Lásd még: %R%S HELP LEVELS bõvebb információkért. CHAN_HELP_SET_XOP - Syntax: SET #szoba XOP {ON | OFF} + Syntax: %s #szoba XOP {ON | OFF} Engedélyezi vagy letiltja az xOP lista rendszert. Ha az XOP be van kapcsolva, akkor AOP/SOP/VOP @@ -4438,7 +4542,7 @@ CHAN_HELP_SET_XOP áttérés nem okoz gondot. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4461,7 +4565,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Syntax: SET #szoba OPNOTICE {ON | OFF} + Syntax: %s #szoba OPNOTICE {ON | OFF} Be/kikapcsolja az opnotice opciót a csatornán. Amikor az op-notice be van kapcsolva, a %S megjegyzést @@ -5024,13 +5128,6 @@ CHAN_SERVADMIN_HELP_DROP droppolhat csatornát,úgy hogy nem használja a szoba jelszavát. -CHAN_SERVADMIN_HELP_SET - - Szervíz admin beállíthatja a csatornát NEMELÉVÜLÕ -re, - ekkor a sorban megelõzi az elévülõket. A szervíz - adminisztrátor beállíthatja anélkül, hogy szoba - jelszót használná. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Syntax: SET #szoba NOEXPIRE {ON | OFF} @@ -5352,8 +5449,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Killeli az összes klónt a hosztról OPER_HELP_CMD_AKILL AKILL Szerkeszti az AKILL listát -OPER_HELP_CMD_SGLINE - SGLINE Szerkeszti az SGLINE listát +OPER_HELP_CMD_SNLINE + SNLINE Szerkeszti az SNLINE listát OPER_HELP_CMD_SQLINE SQLINE Szerkeszti az SQLINE listát OPER_HELP_CMD_SZLINE @@ -5553,19 +5650,19 @@ OPER_HELP_AKILL Korlátozva Szervíz operatornak. -OPER_HELP_SGLINE - Syntax: SGLINE ADD [+lejárat] maszk:indok - SGLINE DEL {maszk | sor-szám | list} - SGLINE LIST [maszk | list] - SGLINE VIEW [maszk | list] - SGLINE CLEAR +OPER_HELP_SNLINE + Syntax: SNLINE ADD [+lejárat] maszk:indok + SNLINE DEL {maszk | sor-szám | list} + SNLINE LIST [maszk | list] + SNLINE VIEW [maszk | list] + SNLINE CLEAR Lehetõséget ad a szervíz opoknak, hogy karbantartsák az - SGLINE listát. Ha egy felhasználó egy valós névvel akar - csatlakozni , ami szerepel az SGLINE listán akkor szervíz + SNLINE listát. Ha egy felhasználó egy valós névvel akar + csatlakozni , ami szerepel az SNLINE listán akkor szervíz nem fogja engedélyezni részére a csatlakozást. - SGLINE ADD hozzáadja a valósnévmaszkot az SGLINE listára + SNLINE ADD hozzáadja a valósnévmaszkot az SNLINE listára a megadott indokkal (amit meg is kell adni). Az elévülést egész számmot kovet egy idoparaméter d (nap), h (óra), m (perc).Ezek kombinálása nem lehetséges(1h30m). @@ -5573,25 +5670,25 @@ OPER_HELP_SGLINE (+30 az 30 napot jelent).Ha +0-át adsz meg akkor nem elévülo lesz.Ha a usermaszk + -al kezdodik akkor elévülést meg kell adni akkor is ha megegyezik az alapértelmezéssel. - Az SGLINE jelenlegi alapértelmezett elévülési ideje + Az SNLINE jelenlegi alapértelmezett elévülési ideje megnézheto a STATS AKILL paranccsal. Jegyzet: a valósnév maszkja tartalmazhat szóközt ezért közte és az indok között az elválasztó karakter a vesszõ. - SGLINE DEL eltávolítja a megadott maszkot az SGLINE listáról, + SNLINE DEL eltávolítja a megadott maszkot az SNLINE listáról, ha jelen van.Ha bejegyzés sorszámot adsz meg akkor azok fognak törlodni. (Lásd a példa alább) - SGLINE LIST kiirja az összes SGLINE bejegyzést; ha + SNLINE LIST kiirja az összes SNLINE bejegyzést; ha egy tetszõleges maszk meg van adva, a lista korlátozva lesz azokra a bejegyzésekre, amelyekre ráillik a maszk. Példa: - SGLINE LIST 2-5,7-9 - Listázza a SGLINE-okat 2-töl 5-ig és 7-tõl 9-ig az - SGLINE listáról + SNLINE LIST 2-5,7-9 + Listázza a SNLINE-okat 2-töl 5-ig és 7-tõl 9-ig az + SNLINE listáról - SGLINE VIEW részletesebb verziója a SGLINE LIST-nek, - és megmutatja, ki készítette a SGLINE bejegyzéseket, + SNLINE VIEW részletesebb verziója a SNLINE LIST-nek, + és megmutatja, ki készítette a SNLINE bejegyzéseket, és mikor jár le, mint a maszkot és az indokot. - SGLINE CLEAR törli az SGLINE bejegyzéseket. + SNLINE CLEAR törli az SNLINE bejegyzéseket. Korlátozva Szervíz operatornak. @@ -5633,7 +5730,7 @@ OPER_HELP_SQLINE SQLINE listáról SQLINE VIEW részletesebb verziója a SQLINE LIST-nek, - és megmutatja, ki készítette a SGLINE bejegyzéseket, + és megmutatja, ki készítette a SNLINE bejegyzéseket, és mikor jár le, mint a maszkot és az indokot. SQLINE CLEAR törli az SQLINE bejegyzéseket. @@ -365,6 +365,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Adesso sei nel gruppo di %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY password @@ -792,9 +800,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nick nel gruppo. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (scade tra %s) + %s (scade tra %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -844,18 +852,15 @@ NICK_SENDPASS_UNAVAILABLE Il comando SENDPASS non è disponibile perché è in uso la criptazione dei dati. NICK_SENDPASS_SUBJECT Password del nick (%s) -NICK_SENDPASS_HEAD - Salve, -NICK_SENDPASS_LINE_1 - Hai richiesto di ricevere via e-mail la password del nick %s. -NICK_SENDPASS_LINE_2 - La password è %s Per ragioni di sicurezza, ti invitiamo a cambiarla il più presto possibile con il comando "/ns set password". -NICK_SENDPASS_LINE_3 - Se non sai perché hai ricevuto questa mail, ignorala. -NICK_SENDPASS_LINE_4 - IMPORTANTE! Non rispondere a questa mail! -NICK_SENDPASS_LINE_5 - Gli amministratori di %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK La password di %s è stata inviata. @@ -869,9 +874,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -916,18 +920,15 @@ NICK_ENTER_REG_CODE Un codice di attivazione è stato inviato a %s. Digita %R%s CONFIRM <codice> per completare la registrazione. NICK_REG_MAIL_SUBJECT Registrazione del nick (%s) -NICK_REG_MAIL_HEAD - Salve, -NICK_REG_MAIL_LINE_1 - Hai richiesto la registrazione del nick %s. -NICK_REG_MAIL_LINE_2 - Digita " %R%s CONFIRM %s " (senza virgolette) per completare la registrazione. -NICK_REG_MAIL_LINE_3 - Se non sai perché hai ricevuto questa e-mail, ignorala. -NICK_REG_MAIL_LINE_4 - NON RISPONDERE A QUESTA MAIL! -NICK_REG_MAIL_LINE_5 - Gli amministratori di %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Il codice di attivazione per %s is %s. NICK_FORCE_REG @@ -1030,6 +1031,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1079,6 +1082,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Il canale %s è stato deregistrato. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET canale opzione parametri @@ -1992,12 +2023,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail responses MEMO_MAIL_SUBJECT Nuovo memo -MEMO_MAIL_TEXT1 - Ciao %s -MEMO_MAIL_TEXT2 - Hai appena ricevuto un nuovo memo da %s. Questo è il memo numero %d. -MEMO_MAIL_TEXT3 - Testo del memo: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s # RSEND responses MEMO_RSEND_PLEASE_WAIT @@ -2497,22 +2530,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Durata di default delle AKILL: 1 minuto OPER_STATS_AKILL_EXPIRE_NONE Durata di default delle AKILL: infinita -OPER_STATS_SGLINE_COUNT - Numero attuale di SGLINE: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Durata di default delle SGLINE: %d giorni -OPER_STATS_SGLINE_EXPIRE_DAY - Durata di default delle SGLINE: 1 giorno -OPER_STATS_SGLINE_EXPIRE_HOURS - Durata di default delle SGLINE: %d ore -OPER_STATS_SGLINE_EXPIRE_HOUR - Durata di default delle SGLINE: 1 ora -OPER_STATS_SGLINE_EXPIRE_MINS - Durata di default delle SGLINE: %d minuti -OPER_STATS_SGLINE_EXPIRE_MIN - Durata di default delle SGLINE: 1 minuto -OPER_STATS_SGLINE_EXPIRE_NONE - Durata di default delle SGLINE: infinita +OPER_STATS_SNLINE_COUNT + Numero attuale di SNLINE: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Durata di default delle SNLINE: %d giorni +OPER_STATS_SNLINE_EXPIRE_DAY + Durata di default delle SNLINE: 1 giorno +OPER_STATS_SNLINE_EXPIRE_HOURS + Durata di default delle SNLINE: %d ore +OPER_STATS_SNLINE_EXPIRE_HOUR + Durata di default delle SNLINE: 1 ora +OPER_STATS_SNLINE_EXPIRE_MINS + Durata di default delle SNLINE: %d minuti +OPER_STATS_SNLINE_EXPIRE_MIN + Durata di default delle SNLINE: 1 minuto +OPER_STATS_SNLINE_EXPIRE_NONE + Durata di default delle SNLINE: infinita OPER_STATS_SQLINE_COUNT Numero attuale di SQLINE: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2637,46 +2670,46 @@ OPER_AKILL_CLEAR La lista AKILL è stata svuotata. OPER_CHANKILL_SYNTAX CHANKILL [+scadenza] {#canale} [motivo] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+durata] {mask | numero-lista}[:motivo]] -OPER_SGLINE_UNSUPPORTED - Spiacente, SGLINE non è disponibile su questa rete. -OPER_SGLINE_EXISTS - %s è già presente nella lista SGLINE. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+durata] {mask | numero-lista}[:motivo]] +OPER_SNLINE_UNSUPPORTED + Spiacente, SNLINE non è disponibile su questa rete. +OPER_SNLINE_EXISTS + %s è già presente nella lista SNLINE. +OPER_SNLINE_ALREADY_COVERED %s è già coperto da %s. -OPER_SGLINE_REACHED_LIMIT - Spiacente, puoi avere un massimo di %d SGLINE. -OPER_SGLINE_ADDED - %s aggiunto alla lista SGLINE. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Spiacente, puoi avere un massimo di %d SNLINE. +OPER_SNLINE_ADDED + %s aggiunto alla lista SNLINE. +OPER_SNLINE_CHANGED Durata di %s modificata. -OPER_SGLINE_NOT_FOUND - %s non trovato nella lista SGLINE. -OPER_SGLINE_NO_MATCH - Nessun record corrispondente nella lista SGLINE. -OPER_SGLINE_DELETED - %s eliminato dalla lista SGLINE. -OPER_SGLINE_DELETED_ONE - Eliminato 1 record dalla lista SGLINE. -OPER_SGLINE_DELETED_SEVERAL - Eliminati %d record dalla lista SGLINE. -OPER_SGLINE_LIST_EMPTY - La lista SGLINE è vuota. -OPER_SGLINE_LIST_HEADER - Lista SGLINE attuale: +OPER_SNLINE_NOT_FOUND + %s non trovato nella lista SNLINE. +OPER_SNLINE_NO_MATCH + Nessun record corrispondente nella lista SNLINE. +OPER_SNLINE_DELETED + %s eliminato dalla lista SNLINE. +OPER_SNLINE_DELETED_ONE + Eliminato 1 record dalla lista SNLINE. +OPER_SNLINE_DELETED_SEVERAL + Eliminati %d record dalla lista SNLINE. +OPER_SNLINE_LIST_EMPTY + La lista SNLINE è vuota. +OPER_SNLINE_LIST_HEADER + Lista SNLINE attuale: Num Mask Motivo -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Lista SGLINE attuale: +OPER_SNLINE_VIEW_HEADER + Lista SNLINE attuale: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (by %s on %s; %s) %s -OPER_SGLINE_CLEAR - La lista SGLINE è stata svuotata. +OPER_SNLINE_CLEAR + La lista SNLINE è stata svuotata. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3287,6 +3320,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registra un nick NICK_HELP_CMD_GROUP GROUP Entra in un gruppo +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Ti identifica per il tuo nick NICK_HELP_CMD_ACCESS @@ -3420,6 +3455,15 @@ NICK_HELP_GROUP Nota: tutti i nick di un gruppo hanno la stessa password. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Sintassi: IDENTIFY password @@ -3482,25 +3526,39 @@ NICK_HELP_ACCESS ACCESS LIST Visualizza la lista di accesso attuale. -NICK_HELP_SET +NICK_HELP_SET_HEAD Sintassi: SET opzione parametri Imposta varie opzioni del nick. opzione può essere una delle seguenti: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Imposta il nome del tuo gruppo +NICK_HELP_CMD_SET_EMAIL EMAIL Associa un indirizzo e-mail al tuo nick +NICK_HELP_CMD_SET_GREET GREET Associa un messaggio di saluto al tuo nick +NICK_HELP_CMD_SET_HIDE HIDE Nasconde alcune informazioni sul tuo nick +NICK_HELP_CMD_SET_ICQ ICQ Associa un numero ICQ al tuo nick +NICK_HELP_CMD_SET_KILL KILL Attiva o disattiva la protezione +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Imposta la lingua utilizzata dai Services +NICK_HELP_CMD_SET_MSG MSG Cambia il metodo di comunicazione usato dai Services +NICK_HELP_CMD_SET_PASSWORD PASSWORD Imposta la password del tuo nick +NICK_HELP_CMD_SET_PRIVATE PRIVATE Nasconde il nick dalla lista (%R%S LIST) +NICK_HELP_CMD_SET_SECURE SECURE Attiva o disattiva la sicurezza +NICK_HELP_CMD_SET_URL URL Associa un URL al tuo nick +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Per usare questo comando, devi prima identificarti con la tua password (digita %R%S HELP IDENTIFY per @@ -3617,26 +3675,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Sintassi: SASET nickname opzione parametri. Imposta varie opzioni del nick. opzione può essere una delle seguenti: - + +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Imposta il nome del gruppo +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Imposta la password del nick +NICK_HELP_CMD_SASET_URL URL Associa un URL al nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associa un indirizzo e-mail al nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associa un numero ICQ al nickname +NICK_HELP_CMD_SASET_GREET GREET Associa un messaggio di saluto al nickname +NICK_HELP_CMD_SASET_KILL KILL Attiva o disattiva la protezione +NICK_HELP_CMD_SASET_SECURE SECURE Attiva o disattiva la sicurezza +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Nasconde il nick dalla lista (%R%S LIST) +NICK_HELP_CMD_SASET_HIDE HIDE Nsconde alcune informazioni sul nick +NICK_HELP_CMD_SASET_MSG MSG Cambia il metodo di comunicazione usato dai servizi +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Evita che il nickname scada +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Digita %R%S HELP SASET opzione per maggiori informazioni su un'opzione specifica. Le opzioni verranno impostate sul @@ -3964,7 +4036,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - I Services Operator possono usare il parametro ALL con tutti i nick. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Sintassi: LIST pattern [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4074,6 +4147,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Registra un canale CHAN_HELP_CMD_SET SET Imposta le opzioni e le informazioni di canale +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4176,7 +4251,15 @@ CHAN_HELP_DROP Deregistra il canale specificato. Può essere usato soltanto da un fondatore di canale. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Sintassi: SET canale opzione parametri Permette al fondatore di un canale di impostare varie @@ -4184,43 +4267,66 @@ CHAN_HELP_SET Opzioni disponibili: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Imposta il fondatore del canale +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Imposta il successore del fondatore del canale +CHAN_HELP_CMD_SET_DESC DESC Imposta la descrizione del canale +CHAN_HELP_CMD_SET_URL URL Associa un URL al canale +CHAN_HELP_CMD_SET_EMAIL EMAIL Associa un indirizzo e-mail al canale +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Imposta un messaggio che sarà inviato agli utenti che entrano nel canale +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Imposta il tipo di ban che sarà usato dai Services +CHAN_HELP_CMD_SET_MLOCK MLOCK Imposta il blocco dei modi di canale +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Mantiene il topic quando il canale non è in uso +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Invia una notifica quando vengono usati i comandi OP/DEOP +CHAN_HELP_CMD_SET_PEACE PEACE Regola l'uso dei comandi critici +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Nasconde il canale dall'output del comando LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Limita l'accesso al canale +CHAN_HELP_CMD_SET_SECURE SECURE Attiva le funzionalità di sicurezza di %S +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Abilita un controllo più severo dello stato di operatore +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Abilita un controllo più severo dello stato di fondatore +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK "Firma" i kick effettuati con il comando KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Imposta il blocco del topic (modificabile solo attraverso il comando TOPIC) +CHAN_HELP_CMD_SET_XOP XOP Seleziona il sistema di privilegi utilizzato +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Digita %R%S HELP option per ottenere maggiori informazioni su un comando specifico. CHAN_HELP_SET_FOUNDER - Sintassi: SET canale FOUNDER nick + Sintassi: %s canale FOUNDER nick Imposta il nuovo fondatore del canale. Il nick specificato deve essere registrato. CHAN_HELP_SET_SUCCESSOR - Sintassi: SET canale SUCCESSOR nick + Sintassi: %s canale SUCCESSOR nick Imposta il successore del fondatore del canale. Se il nick del fondatore scade, o viene deregistrato mentre il canale @@ -4232,13 +4338,13 @@ CHAN_HELP_SET_SUCCESSOR Il nick specificato deve essere registrato. CHAN_HELP_SET_DESC - Sintassi: SET canale DESC descrizione + Sintassi: %s canale DESC descrizione Imposta la descrizione del canale, che viene mostrata con i comandi LIST e INFO. CHAN_HELP_SET_URL - Sintassi: SET canale URL [url] + Sintassi: %s canale URL [url] Associa l'URL specificato al canale. Questo URL sarà mostrato quando qualcuno richiede informazioni relative @@ -4246,7 +4352,7 @@ CHAN_HELP_SET_URL nessun URL, l'URL attuale del canale viene eliminato. CHAN_HELP_SET_EMAIL - Sintassi: SET canale EMAIL [indirizzo] + Sintassi: %s canale EMAIL [indirizzo] Associa l'indirizzo e-mail specificato al canale. Questo indirizzo sarà mostrato quando qualcuno richiede @@ -4255,7 +4361,7 @@ CHAN_HELP_SET_EMAIL del canale viene eliminato. CHAN_HELP_SET_ENTRYMSG - Sintassi: SET canale ENTRYMSG [messaggio] + Sintassi: %s canale ENTRYMSG [messaggio] Imposta il messaggio che sarà inviato con un /notice agli utenti che entrano nel canale. Se non viene @@ -4264,7 +4370,7 @@ CHAN_HELP_SET_ENTRYMSG riceveranno alcun messaggio. CHAN_HELP_SET_BANTYPE - Sintassi: SET canale BANTYPE tipo + Sintassi: %s canale BANTYPE tipo Imposta il tipo di can che sarà usato dai Services in tutte le occasioni in cui dovranno bannare @@ -4278,7 +4384,7 @@ CHAN_HELP_SET_BANTYPE 3: ban nella forma *!*user@*.dominio CHAN_HELP_SET_KEEPTOPIC - Sintassi: SET canale KEEPTOPIC {ON | OFF} + Sintassi: %s canale KEEPTOPIC {ON | OFF} Attiva o disattiva il mantenimento del topic per il canale. Quando il mantenimento del topic è @@ -4287,7 +4393,7 @@ CHAN_HELP_SET_KEEPTOPIC la volta successiva che entra qualcuno. CHAN_HELP_SET_TOPICLOCK - Sintassi: SET canale TOPICLOCK {ON | OFF} + Sintassi: %s canale TOPICLOCK {ON | OFF} Attiva o disattiva il blocco del topic per il canale. Quando il blocco del topic è attivo, @@ -4295,7 +4401,7 @@ CHAN_HELP_SET_TOPICLOCK non attraverso il comando TOPIC. CHAN_HELP_SET_MLOCK - Sintassi: SET canale MLOCK modi + Sintassi: %s canale MLOCK modi Imposta il blocco dei modi per il canale. %S permette di definire vari modi di canale che saranno @@ -4333,7 +4439,7 @@ CHAN_HELP_SET_MLOCK possono essere attivati o disattivati dagli utenti. CHAN_HELP_SET_PEACE - Sintassi: SET canale PEACE {ON | OFF} + Sintassi: %s canale PEACE {ON | OFF} Attiva o disattiva l'opzione "pace" per il canale. Quando l'opzione è attiva, gli utenti non potranno @@ -4342,21 +4448,21 @@ CHAN_HELP_SET_PEACE superiore, attraverso i comandi di %S. CHAN_HELP_SET_PRIVATE - Sintassi: SET canale PRIVATE {ON | OFF} + Sintassi: %s canale PRIVATE {ON | OFF} Attiva o disattiva l'opzione di privacy per il canale. Quando questa opzione è attiva, il canale non sarà incluso nella lista restituita da %R%S LIST. CHAN_HELP_SET_RESTRICTED - Sintassi: SET canale RESTRICTED {ON | OFF} + Sintassi: %s canale RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Sintassi: SET canale SECURE {ON | OFF} + Sintassi: %s canale SECURE {ON | OFF} Attiva o disattiva le funzionalità di sicurezza di %S per il canale. Quando SECURE è attivo, @@ -4365,7 +4471,7 @@ CHAN_HELP_SET_SECURE avranno l'accesso sul canale secondo le liste di accesso. CHAN_HELP_SET_SECUREOPS - Sintassi: SET canale SECUREOPS {ON | OFF} + Sintassi: %s canale SECUREOPS {ON | OFF} Attiva o disattiva l'opzione secure ops per il canale. Quando l'opzione è attiva, gli utenti che non sono nella @@ -4373,7 +4479,7 @@ CHAN_HELP_SET_SECUREOPS di canale. CHAN_HELP_SET_SECUREFOUNDER - Sintassi: SET canale SECUREFOUNDER {ON | OFF} + Sintassi: %s canale SECUREFOUNDER {ON | OFF} Attiva o disattiva l'opzione secure founder per il canale. Quando l'opzione è attiva, solo il vero fondatore @@ -4382,7 +4488,7 @@ CHAN_HELP_SET_SECUREFOUNDER su %S per il canale non potranno. CHAN_HELP_SET_SIGNKICK - Sintassi: SET canale SIGNKICK {ON | LEVEL | OFF} + Sintassi: %s canale SIGNKICK {ON | LEVEL | OFF} Attiva o disattiva i nick "firmati" per il canale. Quando l'opzione è attiva, i kick effettuati con il comando KICK @@ -4395,7 +4501,7 @@ CHAN_HELP_SET_SIGNKICK Per maggiori informazioni, digita %R%S HELP LEVELS. CHAN_HELP_SET_XOP - Sintassi: SET canale XOP {ON | OFF} + Sintassi: %s canale XOP {ON | OFF} Attiva o disattiva il sistema di liste xOP per il canale. Quando XOP è attivo, sarà necessario usare i comandi @@ -4416,7 +4522,7 @@ CHAN_HELP_SET_XOP non causa nessun problema. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4439,7 +4545,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Sintassi: SET canale OPNOTICE {ON | OFF} + Sintassi: %s canale OPNOTICE {ON | OFF} Attiva o disattiva l'opzione op-notice per il canale. Quando l'opzione è attiva, %S invierà un notice al @@ -5022,14 +5128,6 @@ CHAN_SERVADMIN_HELP_DROP possono deregistrare un canale per il quale non si siano identificati. -CHAN_SERVADMIN_HELP_SET - - I Services Operator possono anche impostare l'opzione NOEXPIRE, - in modo da non far scadere i canali anche in caso di inutilizzo. - Inoltre, i Services Operator possono impostare le opzioni per - qualsiasi canale senza aver bisogno di identificarsi sui canali - stessi. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Sintassi: SET canale NOEXPIRE {ON | OFF} @@ -5348,8 +5446,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Killa tutti gli utenti da un certo host OPER_HELP_CMD_AKILL AKILL Manipola la lista AKILL -OPER_HELP_CMD_SGLINE - SGLINE Manipola la lista SGLINE +OPER_HELP_CMD_SNLINE + SNLINE Manipola la lista SNLINE OPER_HELP_CMD_SQLINE SQLINE Manipola la lista SQLINE OPER_HELP_CMD_SZLINE @@ -5547,51 +5645,51 @@ OPER_HELP_AKILL AKILL CLEAR svuota la lista AKILL. -OPER_HELP_SGLINE - Sintassi: SGLINE ADD [+durata] mask:motivo - SGLINE DEL {mask | numero | lista} - SGLINE LIST [mask | lista] - SGLINE VIEW [mask | lista] - SGLINE CLEAR +OPER_HELP_SNLINE + Sintassi: SNLINE ADD [+durata] mask:motivo + SNLINE DEL {mask | numero | lista} + SNLINE LIST [mask | lista] + SNLINE VIEW [mask | lista] + SNLINE CLEAR - Permette ai Services operator di manipolare la lista SGLINE. - Se un utente che si trova nella lista SGLINE cerca di connettersi, + Permette ai Services operator di manipolare la lista SNLINE. + Se un utente che si trova nella lista SNLINE cerca di connettersi, i Services non gli permetterano di proseguire la sua sessione su IRC. - SGLINE ADD aggiunge la mask di realname specificata alla lista + SNLINE ADD aggiunge la mask di realname specificata alla lista sgline per il motivo specificato (che deve essere indicato). durata è specifcato come un intero seguito da una lettera, che può essere d (giorni), h (ore), o m (minuti). Le combinazioni (ad esempio 1h30m) non sono permesse. Se non viene specificata una unità, il valore viene inteso in giorni - (quindi +30 significa 30 giorni). Per aggiungere una SGLINE + (quindi +30 significa 30 giorni). Per aggiungere una SNLINE senza scadenza, bisogna usare +0. Se la usermask indicata inizia con un +, la durata deve essere indicata esplicitamente, anche se è la stessa di default. La durata di default per le - SGLINE può essere trovata con il comando STATS AKILL. + SNLINE può essere trovata con il comando STATS AKILL. Nota: poiché la mask di realname può contenere spazi, il separatore tra la mask e il motivo è un duepunti. - Il comando SGLINE DEL rimuove la mask specificata dalla lista - SGLINE, se è presente. Se viene indicata una lista di numeri, + Il comando SNLINE DEL rimuove la mask specificata dalla lista + SNLINE, se è presente. Se viene indicata una lista di numeri, verrano rimossi i record corrispondenti (vedi l'esempio di LIST). - Il comando SGLINE LIST mostra la lista SGLINE. Se viene usata + Il comando SNLINE LIST mostra la lista SNLINE. Se viene usata una wildcard nella mask, solo i record che corrispondono alla mask vengono mostrati. Se viene indicata una lista di numeri, soltanto quei record vengono mostrati, ad esempio: - SGLINE LIST 2-5,7-9 - Mostra i record della lista SGLINE che hanno numeri da 2 + SNLINE LIST 2-5,7-9 + Mostra i record della lista SNLINE che hanno numeri da 2 a 5 e da 7 a 9. - SGLINE VIEW mostra più informazioni di SGLINE LIST, e indica - chi ha aggiunto una SGLINE, quando è stata aggiunta, e quando + SNLINE VIEW mostra più informazioni di SNLINE LIST, e indica + chi ha aggiunto una SNLINE, quando è stata aggiunta, e quando scade, oltre alla mask di realname e al motivo. - SGLINE CLEAR svuota la lista SGLINE. + SNLINE CLEAR svuota la lista SNLINE. OPER_HELP_SQLINE Sintassi: SQLINE ADD [+durata] mask motivo @@ -5649,7 +5747,7 @@ OPER_HELP_SZLINE SZLINE CLEAR Permette ai Services operator di manipolare la lista SZLINE. - Se un utente il cui IP si trova nella lista SGLINE cerca di + Se un utente il cui IP si trova nella lista SNLINE cerca di connettersi, i Services non gli permetterano di proseguire la sua sessione su IRC (sia che l'IP abbia un host alfa- numerico corrispondente o meno). @@ -374,6 +374,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Je zit nu in de group van %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY wachtwoord @@ -809,9 +817,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicks in de groep. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -861,18 +869,15 @@ NICK_SENDPASS_UNAVAILABLE SENDPASS commando is onbeschikbaar omdat encryptie aanstaat. NICK_SENDPASS_SUBJECT Nick wachtwoord (%s) -NICK_SENDPASS_HEAD - Hoi, -NICK_SENDPASS_LINE_1 - Je hebt het wachtwoord van nick %s via e-mail aangevraagd. -NICK_SENDPASS_LINE_2 - Het wachtwoord is %s Wegens veiligheidsredenen kun je dit het beste zo snel mogelijk veranderen. -NICK_SENDPASS_LINE_3 - Als je niet weet waarom deze email gestuurd is, negeer deze dan. -NICK_SENDPASS_LINE_4 - ANTWOORD NIET OP DEZE E-MAIL! -NICK_SENDPASS_LINE_5 - %s beheerders. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Wachtwoord %s is verstuurd. @@ -885,9 +890,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. @@ -933,18 +937,15 @@ NICK_ENTER_REG_CODE Een verificatiecode is verstuurd naar %s. Type %R%s confirm <verificatiecode> om de registratie te voltooien. NICK_REG_MAIL_SUBJECT Nickname Registratie (%s) -NICK_REG_MAIL_HEAD - Hoi, -NICK_REG_MAIL_LINE_1 - Je hebt een aanvraag ingediend om de nickname %s te registreren. -NICK_REG_MAIL_LINE_2 - Type " %R%s confirm %s " om de registratie te voltooien. -NICK_REG_MAIL_LINE_3 - Als je niet weet waarom deze e-mail naar je gestuurd is, negeer deze dan. -NICK_REG_MAIL_LINE_4 - REAGEER NIET OP DEZE MAIL! -NICK_REG_MAIL_LINE_5 - %s administrators. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Verificatiecode voor %s is %s. NICK_FORCE_REG @@ -1045,6 +1046,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1094,6 +1097,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Kanaal %s is gede-registreerd. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET kanaal optie parameters @@ -2017,12 +2048,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT Nieuwe memo -MEMO_MAIL_TEXT1 - Hoi %s -MEMO_MAIL_TEXT2 - Je hebt zojuist een memo ontvangen van %s. Het gaat om memo nummer %d. -MEMO_MAIL_TEXT3 - Inhoud van de memo: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s ########################################################################### # @@ -2543,22 +2576,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Standaard AKILL verloop tijd: 1 minuut OPER_STATS_AKILL_EXPIRE_NONE Standaard AKILL verloop tijd: Verloopt niet -OPER_STATS_SGLINE_COUNT - Huidig aantal SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Standaard SGLINE verloop tijd: %d dagen -OPER_STATS_SGLINE_EXPIRE_DAY - Standaard SGLINE verloop tijd: 1 dag -OPER_STATS_SGLINE_EXPIRE_HOURS - Standaard SGLINE verloop tijd: %d uur -OPER_STATS_SGLINE_EXPIRE_HOUR - Standaard SGLINE verloop tijd: 1 uur -OPER_STATS_SGLINE_EXPIRE_MINS - Standaard SGLINE verloop tijd: %d minuten -OPER_STATS_SGLINE_EXPIRE_MIN - Standaard SGLINE verloop tijd: 1 minuut -OPER_STATS_SGLINE_EXPIRE_NONE - Standaard SGLINE verloop tijd: Verloopt niet +OPER_STATS_SNLINE_COUNT + Huidig aantal SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Standaard SNLINE verloop tijd: %d dagen +OPER_STATS_SNLINE_EXPIRE_DAY + Standaard SNLINE verloop tijd: 1 dag +OPER_STATS_SNLINE_EXPIRE_HOURS + Standaard SNLINE verloop tijd: %d uur +OPER_STATS_SNLINE_EXPIRE_HOUR + Standaard SNLINE verloop tijd: 1 uur +OPER_STATS_SNLINE_EXPIRE_MINS + Standaard SNLINE verloop tijd: %d minuten +OPER_STATS_SNLINE_EXPIRE_MIN + Standaard SNLINE verloop tijd: 1 minuut +OPER_STATS_SNLINE_EXPIRE_NONE + Standaard SNLINE verloop tijd: Verloopt niet OPER_STATS_SQLINE_COUNT Huidig aantal SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2682,49 +2715,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR De AKILL lijst is leeggemaakt. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+verloop] {mask | toegangslijst}[:reden]] -OPER_SGLINE_UNSUPPORTED - Sorry, SGLINE is niet beschikbaar op dit netwerk. -OPER_SGLINE_EXISTS - %s bestaat al op de SGLINE lijst. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+verloop] {mask | toegangslijst}[:reden]] +OPER_SNLINE_UNSUPPORTED + Sorry, SNLINE is niet beschikbaar op dit netwerk. +OPER_SNLINE_EXISTS + %s bestaat al op de SNLINE lijst. +OPER_SNLINE_ALREADY_COVERED %s is al gedekt door %s. -OPER_SGLINE_REACHED_LIMIT - Sorry, je kan maar %d SGLINEs hebben. -OPER_SGLINE_ADDED - %s toegevoegd aan de SGLINE lijst. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Sorry, je kan maar %d SNLINEs hebben. +OPER_SNLINE_ADDED + %s toegevoegd aan de SNLINE lijst. +OPER_SNLINE_CHANGED Verlooptijd van %s veranderd. -OPER_SGLINE_NOT_FOUND - %s niet gevonden op de SGLINE lijst. -OPER_SGLINE_NO_MATCH - Geen overeenkomsten op de SGLINE lijst. -OPER_SGLINE_DELETED - %s verwijderd van de SGLINE lijst. -OPER_SGLINE_DELETED_ONE - 1 SGLINE verwijderd van de SGLINE lijst. -OPER_SGLINE_DELETED_SEVERAL - %d SGLINEs verwijderd van de SGLINE lijst. -OPER_SGLINE_LIST_EMPTY - SGLINE lijst is leeg. -OPER_SGLINE_LIST_HEADER - Huidige SGLINE lijst: +OPER_SNLINE_NOT_FOUND + %s niet gevonden op de SNLINE lijst. +OPER_SNLINE_NO_MATCH + Geen overeenkomsten op de SNLINE lijst. +OPER_SNLINE_DELETED + %s verwijderd van de SNLINE lijst. +OPER_SNLINE_DELETED_ONE + 1 SNLINE verwijderd van de SNLINE lijst. +OPER_SNLINE_DELETED_SEVERAL + %d SNLINEs verwijderd van de SNLINE lijst. +OPER_SNLINE_LIST_EMPTY + SNLINE lijst is leeg. +OPER_SNLINE_LIST_HEADER + Huidige SNLINE lijst: Nr Mask Reden -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Huidige SGLINE lijst: +OPER_SNLINE_VIEW_HEADER + Huidige SNLINE lijst: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (door %s op %s; %s) %s -OPER_SGLINE_CLEAR - De SGLINE lijst is leeggemaakt. +OPER_SNLINE_CLEAR + De SNLINE lijst is leeggemaakt. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3363,6 +3396,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registreer een nickname NICK_HELP_CMD_GROUP GROUP Bij een groep aanmelden +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Jezelf identificeren met je wachtwoord NICK_HELP_CMD_ACCESS @@ -3495,6 +3530,15 @@ NICK_HELP_GROUP Opmerking: alle nicks in een groep hebben hetzelfde wachtwoord. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Gebruik: IDENTIFY wachtwoord @@ -3553,26 +3597,40 @@ NICK_HELP_ACCESS ACCESS LIST Geeft de huidige toegangslijst weer. -NICK_HELP_SET +NICK_HELP_SET_HEAD Gebruik: SET optie parameters Stelt verscheidene nick opties in. option kan zijn: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Stel de weergave van je groep in Services in +NICK_HELP_CMD_SET_PASSWORD PASSWORD Verander het wachtwoord voor je nick +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Selecteer de taal die Services zal gebruiken voor het versturen van berichten naar jou +NICK_HELP_CMD_SET_URL URL Associeer een URL met je nick +NICK_HELP_CMD_SET_EMAIL EMAIL Associeer een E-mail adres met je nick +NICK_HELP_CMD_SET_ICQ ICQ Associeer een ICQ nummer met je nick +NICK_HELP_CMD_SET_GREET GREET Associeer een begroeting met je nick +NICK_HELP_CMD_SET_KILL KILL Zet bescherming aan of uit +NICK_HELP_CMD_SET_SECURE SECURE Zet nickname beveiliging aan of uit +NICK_HELP_CMD_SET_PRIVATE PRIVATE Zorgt ervoor dat je nick niet verschijnt in een %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Verberg verschillende soorten nick informatie +NICK_HELP_CMD_SET_MSG MSG Verander de communicatiemanier van Services +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Om dit commando te gebruiken moet je je eerst identificeren met je wachtwoord (%R%S HELP IDENTIFY voor meer @@ -3689,26 +3747,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: - + +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -4030,7 +4102,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Services Operators mogen het ALL parameter met elke nick gebruiken. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Gebruik: trefbeeld [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4159,6 +4232,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Registreer een kanaal CHAN_HELP_CMD_SET SET Stel kanaal opties en informatie in +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4260,7 +4335,15 @@ CHAN_HELP_DROP Heft de registratie van het gegeven kanaal op. Kan alleen gebruik wordt door de kanaalstichter. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Gebruik: SET kanaal optie parameters Stelt de kanaalstichter in staat om verschillende kanaal- @@ -4268,42 +4351,65 @@ CHAN_HELP_SET Beschikbare opties: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Stelt de stichter van het kanaal in +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Stelt de opvolger van het kanaal in +CHAN_HELP_CMD_SET_DESC DESC Stelt de kanaalbeschrijving in +CHAN_HELP_CMD_SET_URL URL Associeer een URL met het kanaal +CHAN_HELP_CMD_SET_EMAIL EMAIL Associate een E-mail adres met het kanaal +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Stel een bericht in dat naar de gebruikers wordt gestuurd zodra ze het kanaal binnekomen +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Stelt in hoe Services bans op het kanaal maken +CHAN_HELP_CMD_SET_MLOCK MLOCK Zet kanaal modes vast aan of uit +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Onthoud het topic zoland het kanaal niet in gebruik is +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Stuur een notice wanneer de OP/DEOP commando's worden gebruikt. +CHAN_HELP_CMD_SET_PEACE PEACE Reguleer het gebruik van kritieke commando's +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Verberg een kanaal van het LIST commando +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Limiteer toegang tot het kanaal +CHAN_HELP_CMD_SET_SECURE SECURE Activeer %S veiligheidsopties +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Sterkere controle van de kanaalop status +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Sterkere controle van de stichter status +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Onderteken kicks die worden uitgevoerd met het KICK commando +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Topic kan alleen veranderd worden met TOPIC +CHAN_HELP_CMD_SET_XOP XOP Schakel het gebruikersprivilegesysteem om +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Type %R%S HELP option voor meer informatie over een specifieke optie. CHAN_HELP_SET_FOUNDER - Gebruik: SET kanaal FOUNDER nick + Gebruik: %s kanaal FOUNDER nick Veranderd de stichter van een kanaal. De nieuwe nick moet een geregistreerde nick zijn. CHAN_HELP_SET_SUCCESSOR - Gebruik: SET kanaal SUCCESSOR nick + Gebruik: %s kanaal SUCCESSOR nick Veranderd de opvolger van een kanaal. Als de nick van de stichter verloopt of de registratie ervan wordt geannuleerd @@ -4315,13 +4421,13 @@ CHAN_HELP_SET_SUCCESSOR geregistreerde nick zijn. CHAN_HELP_SET_DESC - Gebruik: SET kanaal DESC beschrijving + Gebruik: %s kanaal DESC beschrijving Stelt de beschrijving van een kanaal in, die weergegeven wordt door de LIST en INFO commando's. CHAN_HELP_SET_URL - Gebruik: SET kanaal URL [url] + Gebruik: %s kanaal URL [url] Associeer de gegeven URL met het kanaal. Deze URL zal worden weergegeven wanneer iemand informatie over het kanaal op- @@ -4329,7 +4435,7 @@ CHAN_HELP_SET_URL wordt de URL voor het kanaal verwijderd. CHAN_HELP_SET_EMAIL - Gebruik: SET kanaal EMAIL [adres] + Gebruik: %s kanaal EMAIL [adres] Associeer het gegeven e-mail adres met het kanaal. Dit adres zal worden weergegeven wanneer iemand informatie over het @@ -4338,7 +4444,7 @@ CHAN_HELP_SET_EMAIL verwijderd. CHAN_HELP_SET_ENTRYMSG - Gebruik: SET kanaal ENTRYMSG [bericht] + Gebruik: %s kanaal ENTRYMSG [bericht] Stelt het bericht in dat via /notice zal worden verstuurd aan gebruikers die het kanaal binnenkomen. Als er geen @@ -4346,7 +4452,7 @@ CHAN_HELP_SET_ENTRYMSG als iemand het kanaal binnenkomt. CHAN_HELP_SET_BANTYPE - Gebruik: SET kanaal BANTYPE bantype + Gebruik: %s kanaal BANTYPE bantype Stelt het bantype in dat gebruikt zal worden door services wanneer ze een ban moet zetten op je kanaal. @@ -4359,7 +4465,7 @@ CHAN_HELP_SET_BANTYPE 3: ban in het formaat *!*gebruiker@*.domein CHAN_HELP_SET_KEEPTOPIC - Gebruik: SET kanaal KEEPTOPIC {ON | OFF} + Gebruik: %s kanaal KEEPTOPIC {ON | OFF} Zet de topicbehoud optie aan of uit voor een kanaal. Wanneer topicbehoud aan staat zal het topic van het @@ -4369,7 +4475,7 @@ CHAN_HELP_SET_KEEPTOPIC teruggezet. CHAN_HELP_SET_TOPICLOCK - Gebruik: SET kanaal TOPICLOCK {ON | OFF} + Gebruik: %s kanaal TOPICLOCK {ON | OFF} Zet de topicslot optie aan of uit voor een kanaal. Wanneer topicslot aan staat zal %S het niet toestaan om @@ -4377,7 +4483,7 @@ CHAN_HELP_SET_TOPICLOCK alleen veranderd worden met het TOPIC commando. CHAN_HELP_SET_MLOCK - Gebruik: SET kanaal MLOCK modes + Gebruik: %s kanaal MLOCK modes Stelt de mode-slot paramenter in voor het kanaal. %S staat je toe om verschillen kanaalmodes altijd aan of uit @@ -4413,7 +4519,7 @@ CHAN_HELP_SET_MLOCK vrij ingesteld worden met /MODE. CHAN_HELP_SET_PEACE - Gebruik: SET kanaal PEACE {ON | OFF} + Gebruik: %s kanaal PEACE {ON | OFF} Zet de vrede optie aan of uit voor een kanaal. Wanneer vrede aanstaat kan een gebruiker niemand kicken, bannen, @@ -4422,21 +4528,21 @@ CHAN_HELP_SET_PEACE van zichzelf via de %S commando's. CHAN_HELP_SET_PRIVATE - Gebruik: SET kanaal PRIVATE {ON | OFF} + Gebruik: %s kanaal PRIVATE {ON | OFF} Zet de prive optie aan of uit voor een kanaal. Wanneer de prive optie aan staat zal %R%S LIST het kanaal in geen enkele lijst weergeven. CHAN_HELP_SET_RESTRICTED - Gebruik: SET kanaal RESTRICTED {ON | OFF} + Gebruik: %s kanaal RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Gebruik: SET kanaal SECURE {ON | OFF} + Gebruik: %s kanaal SECURE {ON | OFF} Zet %S's veiligheidsfuncties aan of uit voor een kanaal. Wanneer SECURE aan staat zullen alleen gebruikers die @@ -4445,14 +4551,14 @@ CHAN_HELP_SET_SECURE zoals geregeld door de toegangslijst. CHAN_HELP_SET_SECUREOPS - Gebruik: SET kanaal SECUREOPS {ON | OFF} + Gebruik: %s kanaal SECUREOPS {ON | OFF} Zet de veilige ops optie aan of uit voor een kanaal. Wanneer veilige ops aan staat mogen gebruikers die niet op de toegangslijst staan geen kanaalop status krijgen. CHAN_HELP_SET_SECUREFOUNDER - Gebruik: SET kanaal SECUREFOUNDER {ON | OFF} + Gebruik: %s kanaal SECUREFOUNDER {ON | OFF} Zet de veilige stichter optie aan of uit voor een kanaal. Wanneer veilige stichter aan staat zal alleen de echte @@ -4461,7 +4567,7 @@ CHAN_HELP_SET_SECUREFOUNDER die alleen geidentificeerd zijn met %S. CHAN_HELP_SET_SIGNKICK - Gebruik: SET kanaal SIGNKICK {ON | LEVEL | OFF} + Gebruik: %s kanaal SIGNKICK {ON | LEVEL | OFF} Zet ondertekende kicks aan of uit voor een kanaal. Wanneer SIGNKICK aan staat zullen kicks die uitgevoerd @@ -4474,7 +4580,7 @@ CHAN_HELP_SET_SIGNKICK Zie %R%S HELP LEVELS voor meer informatie. CHAN_HELP_SET_XOP - Gebruik: SET kanaal XOP {ON | OFF} + Gebruik: %s kanaal XOP {ON | OFF} Zet het xOP lijsten systeem aan of uit voor een kanaal. Wanneer XOP aan staat moet je de AOP/SOP/VOP @@ -4497,7 +4603,7 @@ CHAN_HELP_SET_XOP systeem brengt echter geen problemen met zich mee. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4520,7 +4626,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Gebruik: SET kanaal OPNOTICE {ON | OFF} + Gebruik: %s kanaal OPNOTICE {ON | OFF} Zet de op-notificatie optie aan of uit voor een kanaal. Wanneer op-notificatie aan staat zal %S een notice naar @@ -5082,13 +5188,6 @@ CHAN_SERVADMIN_HELP_DROP Services Operators kunnen elk kanaal droppen, ook al zijn ze niet voor het betreffende kanaal geindtificeerd. -CHAN_SERVADMIN_HELP_SET - - Services Operatorstrators kunnen ook de NOEXPIRE optie - instellen, waarmee kanalen niet kunnen verlopen. Ook - kunnen ze elke optie voor elk kanaal zet zonder zich te - identificeren met het wachtwoord voor het kanaal. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Gebruik: SET kanaal NOEXPIRE {ON | OFF} @@ -5423,8 +5522,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Kill alle gebruikers met een bepaalde hostmask OPER_HELP_CMD_AKILL AKILL Beheer de AKILL lijst -OPER_HELP_CMD_SGLINE - SGLINE Beheer de SGLINE lijst +OPER_HELP_CMD_SNLINE + SNLINE Beheer de SNLINE lijst OPER_HELP_CMD_SQLINE SQLINE Beheer de SQLINE lijst OPER_HELP_CMD_SZLINE @@ -5628,50 +5727,50 @@ OPER_HELP_AKILL AKILL CLEAR maakt de AKILL lijst leeg. -OPER_HELP_SGLINE - Gebruik: SGLINE ADD [+verlooptijd] mask reden - SGLINE DEL {mask | entry-nr | lijst} - SGLINE LIST [mask | lijst] - SGLINE VIEW [mask | lijst] - SGLINE CLEAR +OPER_HELP_SNLINE + Gebruik: SNLINE ADD [+verlooptijd] mask reden + SNLINE DEL {mask | entry-nr | lijst} + SNLINE LIST [mask | lijst] + SNLINE VIEW [mask | lijst] + SNLINE CLEAR - Stelt Services operators in staat de SGLINE lijst te beheren. - Als een gebruiker die overeenkomt met een SGLINE mask probeert + Stelt Services operators in staat de SNLINE lijst te beheren. + Als een gebruiker die overeenkomt met een SNLINE mask probeert te verbinden zullen Services deze gebruiker niet toestaan zijn of haar IRC sessie voort te zetten. - SGLINE ADD voeg het gegeven user@host mask toe aan de SGLINE + SNLINE ADD voeg het gegeven user@host mask toe aan de SNLINE lijst met de gegeven reden (die moet worden gegeven). verlooptijd wordt gespecificeerd als een getal waarachter d (dagen), h (uur), of m (minuten) geplaatst wordt. Combinaties (zoals 1h30m) zijn niet toegestaan. Als er geen d, h of m wordt meegegeven, is het standaard dagen (dus +30 zelfstandig betekent - 30 dagen). Om een SGLINE die niet verloopt toe te voegen, gebruik je + 30 dagen). Om een SNLINE die niet verloopt toe te voegen, gebruik je +0. Als de usermask die toegevoegd moet worden met een + begint, is een verlooptijd verplicht, zelfs als die overeenkomt met de standaard verlooptijd. De huidige standaard verlooptijd voor een - SGLINE kan gevonden worden met het STATS AKILL commando. + SNLINE kan gevonden worden met het STATS AKILL commando. - Het SGLINE DEL commando verwijdert het gegeven mask van de SGLINE + Het SNLINE DEL commando verwijdert het gegeven mask van de SNLINE lijst als deze erop staat. Als er een lijst van entry-nummers is opgegeven zullen die verwijderd worden. (Zie het voorbeeld voor LIST hier onder.) - Her SGLINE LIST commando geeft de SGLINE lijst weer. - Als een mask met een * is gegeven zullen alleen de SGLINEs die + Her SNLINE LIST commando geeft de SNLINE lijst weer. + Als een mask met een * is gegeven zullen alleen de SNLINEs die overeenkomen met het mask worden weergegeven. Als een lijst van entry-nummers is gegeven worden alleen die weergegeven. Bijvoorbeeld: - SGLINE LIST 2-5,7-9 - Geeft SGLINEs 2 t/m 5 en 7 t/m 9 weer. + SNLINE LIST 2-5,7-9 + Geeft SNLINEs 2 t/m 5 en 7 t/m 9 weer. - SGLINE VIEW is een versie van SGLINE LIST die meer informatie - geeft: de naam van degene die de SGLINE toe heeft gevoegd, de datum + SNLINE VIEW is een versie van SNLINE LIST die meer informatie + geeft: de naam van degene die de SNLINE toe heeft gevoegd, de datum waarop dit gebeurde, waneer deze verloopt, en de user@host mask en de reden. - SGLINE CLEAR maakt de SGLINE lijst leeg. + SNLINE CLEAR maakt de SNLINE lijst leeg. OPER_HELP_SQLINE Gebruik: SQLINE ADD [+verlooptijd] mask reden @@ -454,6 +454,16 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Nale¿ysz teraz do grupy %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. + +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. + +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY has³o @@ -1019,10 +1029,10 @@ NICK_GLIST_FOOTER %d nicków w grupie. NICK_GLIST_REPLY - %c%s + %s (wygasa za %s) -NICK_GLIST_REPLY_ADMIN - %c%s (wygasa za %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -1086,24 +1096,15 @@ NICK_SENDPASS_UNAVAILABLE NICK_SENDPASS_SUBJECT Has³o do nicka %s -NICK_SENDPASS_HEAD - Witaj! - -NICK_SENDPASS_LINE_1 - Za¿±da³e¶(a¶) wys³ania has³a do nicka %s na e-mail. - -NICK_SENDPASS_LINE_2 - Twoje has³o to: %s - Dla w³asnego bezpieczeñstwa nale¿y to has³o natychmiast zmieniæ na inne. - -NICK_SENDPASS_LINE_3 - Je¶li nie wiesz dlaczego ta wiadomo¶æ dotar³a do Ciebie zignoruj j±. Je¶li ta sytuacja bêdzie siê powtarzaæ skontaktuj siê z administratorem sieci. - -NICK_SENDPASS_LINE_4 - PROSZÊ NIE ODPOWIADAÆ NA T¡ WIADOMO¦Æ! - -NICK_SENDPASS_LINE_5 - Administratorzy sieci %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Has³o do nicka %s zosta³o wys³ane. @@ -1118,9 +1119,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -1179,22 +1179,15 @@ NICK_ENTER_REG_CODE NICK_REG_MAIL_SUBJECT Rejestracja nicka %s -NICK_REG_MAIL_HEAD - Witaj! - -NICK_REG_MAIL_LINE_1 - Chcesz zarejestrowaæ nastêpuj±cy nick: %s. - -NICK_REG_MAIL_LINE_2 - Proszê napisaæ %R%s CONFIRM %s aby dokoñczyæ rejestracjê. - -NICK_REG_MAIL_LINE_3 - Je¶li nie wiesz dlaczego ta wiadomo¶æ dotar³a do Ciebie zignoruj j±. Je¶li sytuacja bêdzie siê powtarzaæ skontaktuj siê z administratorem sieci. -NICK_REG_MAIL_LINE_4 - PROSZÊ NIE ODPOWIADAÆ NA T¡ WIADOMO¦Æ! - -NICK_REG_MAIL_LINE_5 - Administratorzy sieci %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Kod rejestracyjny dla %s to %s. @@ -1339,6 +1332,9 @@ CHAN_LEVEL_OWNER CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders + # Automatic responses CHAN_IS_REGISTERED Ten kana³ zosta³ zarejestrowany z %s. @@ -1403,6 +1399,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Kana³ %s zosta³ odrejestrowany. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET kana³ opcja parametry @@ -2630,14 +2654,14 @@ MEMO_INFO_X_NOTIFY_SIGNON MEMO_MAIL_SUBJECT Nowa wiadomo¶æ -MEMO_MAIL_TEXT1 - Witaj %s! - -MEMO_MAIL_TEXT2 - W³a¶nie nadesz³a now± wiadomo¶æ od %s, ma numer %d. - -MEMO_MAIL_TEXT3 - Tre¶æ wiadomo¶ci: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s # RSEND responses MEMO_RSEND_PLEASE_WAIT @@ -3313,29 +3337,29 @@ OPER_STATS_AKILL_EXPIRE_MIN OPER_STATS_AKILL_EXPIRE_NONE Domy¶lny czas wygasania AKILL: nie wygasa -OPER_STATS_SGLINE_COUNT - Aktualna ilo¶æ wpisów SGLINE: %d +OPER_STATS_SNLINE_COUNT + Aktualna ilo¶æ wpisów SNLINE: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Domy¶lny czas wygasania SGLINE: %d dni +OPER_STATS_SNLINE_EXPIRE_DAYS + Domy¶lny czas wygasania SNLINE: %d dni -OPER_STATS_SGLINE_EXPIRE_DAY - Domy¶lny czas wygasania SGLINE: 1 dzieñ +OPER_STATS_SNLINE_EXPIRE_DAY + Domy¶lny czas wygasania SNLINE: 1 dzieñ -OPER_STATS_SGLINE_EXPIRE_HOURS - Domy¶lny czas wygasania SGLINE: %d godzin(y) +OPER_STATS_SNLINE_EXPIRE_HOURS + Domy¶lny czas wygasania SNLINE: %d godzin(y) -OPER_STATS_SGLINE_EXPIRE_HOUR - Domy¶lny czas wygasania SGLINE: 1 godzina +OPER_STATS_SNLINE_EXPIRE_HOUR + Domy¶lny czas wygasania SNLINE: 1 godzina -OPER_STATS_SGLINE_EXPIRE_MINS - Domy¶lny czas wygasania SGLINE: %d minut(y) +OPER_STATS_SNLINE_EXPIRE_MINS + Domy¶lny czas wygasania SNLINE: %d minut(y) -OPER_STATS_SGLINE_EXPIRE_MIN - Domy¶lny czas wygasania SGLINE: 1 minuta +OPER_STATS_SNLINE_EXPIRE_MIN + Domy¶lny czas wygasania SNLINE: 1 minuta -OPER_STATS_SGLINE_EXPIRE_NONE - Domy¶lny czas wygasania SGLINE: nie wygasa +OPER_STATS_SNLINE_EXPIRE_NONE + Domy¶lny czas wygasania SNLINE: nie wygasa OPER_STATS_SQLINE_COUNT Aktualna ilo¶æ wpisów SQLINE: %d @@ -3504,63 +3528,63 @@ OPER_AKILL_CLEAR OPER_CHANKILL_SYNTAX CHANKILL [+czas-trwania] {#kana³} [powód] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+czas-trwania] {maska | pozycja} [powód]] +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+czas-trwania] {maska | pozycja} [powód]] -OPER_SGLINE_UNSUPPORTED - Komenda SGLINE nie jest dostêpna w tej sieci. +OPER_SNLINE_UNSUPPORTED + Komenda SNLINE nie jest dostêpna w tej sieci. -OPER_SGLINE_EXISTS - %s ju¿ istnieje na li¶cie SGLINE. +OPER_SNLINE_EXISTS + %s ju¿ istnieje na li¶cie SNLINE. -OPER_SGLINE_ALREADY_COVERED +OPER_SNLINE_ALREADY_COVERED %s ju¿ jest obejmowane przez %s. -OPER_SGLINE_REACHED_LIMIT - Mo¿esz mieæ tylko %d wpisów na li¶cie SGLINE. +OPER_SNLINE_REACHED_LIMIT + Mo¿esz mieæ tylko %d wpisów na li¶cie SNLINE. -OPER_SGLINE_ADDED - %s dodano do listy SGLINE. +OPER_SNLINE_ADDED + %s dodano do listy SNLINE. -OPER_SGLINE_CHANGED +OPER_SNLINE_CHANGED Zmieniono czas wygasania %s. -OPER_SGLINE_NOT_FOUND - %s nie znaleziono na li¶cie SGLINE. +OPER_SNLINE_NOT_FOUND + %s nie znaleziono na li¶cie SNLINE. -OPER_SGLINE_NO_MATCH - Nie znaleziono pasuj±cych wpisów na li¶cie SGLINE. +OPER_SNLINE_NO_MATCH + Nie znaleziono pasuj±cych wpisów na li¶cie SNLINE. -OPER_SGLINE_DELETED - %s usuniêto z listy SGLINE. +OPER_SNLINE_DELETED + %s usuniêto z listy SNLINE. -OPER_SGLINE_DELETED_ONE - Usuniêto 1 wpis z listy SGLINE. +OPER_SNLINE_DELETED_ONE + Usuniêto 1 wpis z listy SNLINE. -OPER_SGLINE_DELETED_SEVERAL - Usuniêto %d wpisy(ów) z listy SGLINE. +OPER_SNLINE_DELETED_SEVERAL + Usuniêto %d wpisy(ów) z listy SNLINE. -OPER_SGLINE_LIST_EMPTY - Lista SGLINE jest pusta. +OPER_SNLINE_LIST_EMPTY + Lista SNLINE jest pusta. -OPER_SGLINE_LIST_HEADER - Aktualna lista SGLINE: +OPER_SNLINE_LIST_HEADER + Aktualna lista SNLINE: Nr Maska Powód -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Aktualna lista SGLINE: +OPER_SNLINE_VIEW_HEADER + Aktualna lista SNLINE: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (przez %s na %s; %s) %s -OPER_SGLINE_CLEAR - Lista SGLINE zosta³a wyczyszczona. +OPER_SNLINE_CLEAR + Lista SNLINE zosta³a wyczyszczona. # SQLINE responses OPER_SQLINE_SYNTAX @@ -4330,6 +4354,9 @@ NICK_HELP_CMD_REGISTER NICK_HELP_CMD_GROUP GROUP Do³±cza nick do wskazanej grupy +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group + NICK_HELP_CMD_IDENTIFY IDENTIFY Identyfikuje w³a¶ciciela nicka @@ -4486,6 +4513,15 @@ NICK_HELP_GROUP Uwaga: wszystkie nicki w grupie maj± to samo has³o. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Sk³adnia: IDENTIFY has³o @@ -4543,26 +4579,40 @@ NICK_HELP_ACCESS ACCESS LIST Wy¶wietla aktualn± listê dostêpu. -NICK_HELP_SET +NICK_HELP_SET_HEAD Sk³adnia: SET opcja parametry Ustawia ró¿ne opcje nicka. Dostêpne opcje to: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Ustawia nick reprezentuj±cy grupê nicków +NICK_HELP_CMD_SET_PASSWORD PASSWORD Ustawia has³o do nicka +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Ustawia jêzyk w którym serwisy bêd± wysy³a³y komunikaty +NICK_HELP_CMD_SET_URL URL Przypisuje adres www do nicka +NICK_HELP_CMD_SET_EMAIL EMAIL Przypisuje adres e-mail do nicka +NICK_HELP_CMD_SET_ICQ ICQ Przypisuje numer ICQ do nicka +NICK_HELP_CMD_SET_GREET GREET Przypisuje komunikat powitalny do nicka +NICK_HELP_CMD_SET_KILL KILL W³±cza lub wy³±cza ochronê nicka +NICK_HELP_CMD_SET_SECURE SECURE W³±cza lub wy³±cza bezpieczeñstwo nicka +NICK_HELP_CMD_SET_PRIVATE PRIVATE Zapobiega wy¶wietlaniu nicka po wydaniu polecenia: %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Ukrywa poszczególne informacje o nicku +NICK_HELP_CMD_SET_MSG MSG Zmienia sposób komunikacji serwisów +NICK_HELP_CMD_SET_AUTOOP AUTOOP W³±cza lub wy³±cza automatyczne opowanie +NICK_HELP_SET_TAIL Aby u¿yæ tej komendy musisz siê zidentyfikowaæ z u¿yciem Twojego has³a. Aby uzyskaæ wiêcej informacji wpisz: @@ -4683,28 +4733,43 @@ NICK_HELP_SET_AUTOOP W³±cza lub wy³±cza automatyczne nadawanie uprawnieñ przy wchodzeniu na kana³. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Sk³adnia: SASET nick opcja parametry. Ustawia ró¿ne opcje nicka wskazanemu u¿ytkownikowi. Dostêpne opcje to: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Ustawia nick reprezentuj±cy grupê nicków +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Ustawia has³o do nicka +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Ustawia jêzyk w którym serwisy bêd± wysy³a³y komunikaty +NICK_HELP_CMD_SASET_URL URL Przypisuje adres www do nicka +NICK_HELP_CMD_SASET_EMAIL EMAIL Przypisuje adres e-mail do nicka +NICK_HELP_CMD_SASET_ICQ ICQ Przypisuje numer ICQ do nicka +NICK_HELP_CMD_SASET_GREET GREET Przypisuje komunikat powitalny do nicka +NICK_HELP_CMD_SASET_KILL KILL W³±cza lub wy³±cza ochronê nicka +NICK_HELP_CMD_SASET_SECURE SECURE W³±cza lub wy³±cza bezpieczeñstwo nicka +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Zapobiega wy¶wietlaniu nicka po wydaniu polecenia: %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Ukrywa poszczególne informacje o nicku +NICK_HELP_CMD_SASET_MSG MSG Zmienia sposób komunikacji serwisów +NICK_HELP_CMD_SASET_AUTOOP AUTOOP W³±cza lub wy³±cza automatyczne opowanie +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Zapobiega wyga¶niêciu nicka +NICK_HELP_SASET_TAIL Aby uzyskaæ wiêcej informacji o danej opcji wpisz: %R%S HELP SASET opcja @@ -5029,8 +5094,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Administratorzy serwisów mog± u¿ywaæ parametru - ALL dla ka¿dego nicka. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Sk³adnia: LIST wzorzec [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -5143,6 +5208,9 @@ CHAN_HELP_CMD_REGISTER CHAN_HELP_CMD_SET SET Modyfikuje ustawienia kana³u +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information + CHAN_HELP_CMD_QOP QOP Modify the list of QOP users @@ -5272,7 +5340,15 @@ CHAN_HELP_DROP Usuwa podany kana³. Komenda mo¿e zostaæ u¿yta jedynie przez w³a¶ciciela kana³u. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Sk³adnia: SET kana³ opcja parametry Pozwala w³a¶cicielowi kana³u na zmianê ro¿nych @@ -5280,42 +5356,65 @@ CHAN_HELP_SET Dostêpne opcje: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Ustawia nick w³a¶ciciela kana³u +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Ustawia nick spadkobiercy kana³u +CHAN_HELP_CMD_SET_DESC DESC Ustawia opis kana³u +CHAN_HELP_CMD_SET_URL URL Przypisuje adres www do kana³u +CHAN_HELP_CMD_SET_EMAIL EMAIL Przypisuje adres e-mail do kana³u +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Ustawia wiadomo¶æ, która bêdzie wysy³ana do u¿ytkowników wchodz±cych na kana³ +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Ustawia sposób banowania przez serwisy +CHAN_HELP_CMD_SET_MLOCK MLOCK Blokuje zdejmowanie lub zak³adanie flag +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Zapamiêtuje temat kiedy kana³ jest pusty +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Wysy³a powiadomienie kiedy zostaj± u¿yte komendy OP/DEOP +CHAN_HELP_CMD_SET_PEACE PEACE Reguluje u¿ycie krytycznych komend +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Zapobiega wy¶wietlaniu kana³u po wydaniu polecenia LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Ogranicza dostêp do kana³u +CHAN_HELP_CMD_SET_SECURE SECURE W³±cza lub wy³±cza bezpieczeñstwo kana³u +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS ¦ci¶le kontroluje status operatorów +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER ¦ci¶le kontroluje status w³a¶ciciela +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Podpisuje kicki kiedy u¿yto komendy KICK +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Ogranicza mo¿liwo¶æ zmiany tematu +CHAN_HELP_CMD_SET_XOP XOP W³±cza system uprawnieñ xOP (u¿ycie komend SOP, AOP, HOP, VOP) - PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_PERSIST + PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Aby uzyskaæ wiêcej informacji o danej opcji wpisz: %R%S HELP SET opcja CHAN_HELP_SET_FOUNDER - Sk³adnia: SET kana³ FOUNDER nick + Sk³adnia: %s kana³ FOUNDER nick Zmienia w³a¶ciciela kana³u. Nowy nick musi byæ zarejestrowany. CHAN_HELP_SET_SUCCESSOR - Sk³adnia: SET kana³ SUCCESSOR nick + Sk³adnia: %s kana³ SUCCESSOR nick Ustawia spadkobiercê kana³u. Je¶li nick w³a¶ciciela wyga¶nie lub zostanie usuniêty kana³ zostaje przekazany @@ -5324,33 +5423,33 @@ CHAN_HELP_SET_SUCCESSOR liczby kana³ów (%d) to kana³ zostanie odrejestrowany. CHAN_HELP_SET_DESC - Sk³adnia: SET kana³ DESC opis + Sk³adnia: %s kana³ DESC opis Ustawia opis kana³u widoczny po wydaniu polecenia LIST oraz INFO. CHAN_HELP_SET_URL - Sk³adnia: SET kana³ URL [url] + Sk³adnia: %s kana³ URL [url] Przypisuje adres strony www do kana³u. Adres bêdzie widoczny po u¿yciu polecenia INFO. Komenda wywo³ana bez parametru usuwa wcze¶niej ustawiony adres. CHAN_HELP_SET_EMAIL - Sk³adnia: SET kana³ EMAIL [adres] + Sk³adnia: %s kana³ EMAIL [adres] Przypisuje adres e-mail do kana³u. Adres bêdzie widoczny po u¿yciu polecenia INFO. Komenda wywo³ana bez parametru usuwa wcze¶niej ustawiony adres. CHAN_HELP_SET_ENTRYMSG - Sk³adnia: SET kana³ ENTRYMSG [tre¶æ] + Sk³adnia: %s kana³ ENTRYMSG [tre¶æ] Ustawia tekst powiadomienia wysy³anego poprzez /notice do u¿ytkowników wchodz±cych na kana³. Komenda wywo³ana bez parametru usuwa wcze¶niej ustawion± wiadomo¶æ. CHAN_HELP_SET_BANTYPE - Sk³adnia: SET kana³ BANTYPE typ + Sk³adnia: %s kana³ BANTYPE typ Ustala typ banów zak³adanych przez serwisy. @@ -5363,7 +5462,7 @@ CHAN_HELP_SET_BANTYPE 3: ban w postaci *!*ident@*.domena CHAN_HELP_SET_KEEPTOPIC - Sk³adnia: SET kana³ KEEPTOPIC {ON | OFF} + Sk³adnia: %s kana³ KEEPTOPIC {ON | OFF} W³±cza lub wy³±cza opcjê zapamiêtywania tematu. Kiedy ta opcja jest w³±czona %S ustawi ostatni @@ -5371,7 +5470,7 @@ CHAN_HELP_SET_KEEPTOPIC pierwsza osoba. CHAN_HELP_SET_TOPICLOCK - Sk³adnia: SET kana³ TOPICLOCK {ON | OFF} + Sk³adnia: %s kana³ TOPICLOCK {ON | OFF} W³±cza lub wy³±cza opcjê blokowania tematu kana³u. @@ -5379,7 +5478,7 @@ CHAN_HELP_SET_TOPICLOCK zmianê tematu tylko poprzez wydanie komendy TOPIC. CHAN_HELP_SET_MLOCK - Sk³adnia: SET kana³ MLOCK flagi + Sk³adnia: %s kana³ MLOCK flagi Ustawia blokadê flag kana³owych. %S pozwala na definiowanie, które flag kana³owe maj± byæ zawsze @@ -5415,7 +5514,7 @@ CHAN_HELP_SET_MLOCK Wy³±cza blokowanie flag - mog± byæ zmieniane dowolnie. CHAN_HELP_SET_PEACE - Sk³adnia: SET kana³ PEACE {ON | OFF} + Sk³adnia: %s kana³ PEACE {ON | OFF} W³±cza lub wy³±cza opcjê PEACE dla kana³u. W³±czenie tej opcji uniemo¿liwia wykopanie, @@ -5424,7 +5523,7 @@ CHAN_HELP_SET_PEACE korzystaj±c z poleceñ serwisu %S. CHAN_HELP_SET_PRIVATE - Sk³adnia: SET kana³ PRIVATE {ON | OFF} + Sk³adnia: %s kana³ PRIVATE {ON | OFF} W³±cza lub wy³±cza opcjê PRIVATE dla kana³u. Kiedy ta opcja jest w³±czona kana³ nie bêdzie @@ -5432,7 +5531,7 @@ CHAN_HELP_SET_PRIVATE %R%S LIST CHAN_HELP_SET_RESTRICTED - Sk³adnia: SET kana³ RESTRICTED {ON | OFF} + Sk³adnia: %s kana³ RESTRICTED {ON | OFF} W³±cza lub wy³±cza opcjê ograniczonego dostêpu do kana³u. Po w³±czeniu tej opcji tylko osoby znajduj±ce siê na @@ -5440,7 +5539,7 @@ CHAN_HELP_SET_RESTRICTED u¿ytkownicy bêd± banowani, a nastêpnie usuwani z kana³u. CHAN_HELP_SET_SECURE - Sk³adnia: SET kana³ SECURE {ON | OFF} + Sk³adnia: %s kana³ SECURE {ON | OFF} W³±cza lub wy³±cza opcje bezpieczeñstwa kana³u. Po w³±czeniu tej opcji tylko zarejestrowani @@ -5449,7 +5548,7 @@ CHAN_HELP_SET_SECURE wynikaj±ce z wpisów na li¶cie dostêpu. CHAN_HELP_SET_SECUREOPS - Sk³adnia: SET kana³ SECUREOPS {ON | OFF} + Sk³adnia: %s kana³ SECUREOPS {ON | OFF} W³±cza lub wy³±cza opcjê SECUREOPS dla kana³u. Kiedy ta opcja jest w³±czona u¿ytkownicy bez wpisu @@ -5457,7 +5556,7 @@ CHAN_HELP_SET_SECUREOPS mogli posiadaæ statusu operatora. CHAN_HELP_SET_SECUREFOUNDER - Sk³adnia: SET kana³ SECUREFOUNDER {ON | OFF} + Sk³adnia: %s kana³ SECUREFOUNDER {ON | OFF} W³±cza lub wy³±cza opcjê bezpiecznego w³a¶ciciela. Ustawienie tej opcji powoduje ograniczenie uprawnieñ @@ -5468,7 +5567,7 @@ CHAN_HELP_SET_SECUREFOUNDER dla jednego u¿ytkownika. CHAN_HELP_SET_SIGNKICK - Sk³adnia: SET kana³ SIGNKICK {ON | LEVEL | OFF} + Sk³adnia: %s kana³ SIGNKICK {ON | LEVEL | OFF} W³±cza lub wy³±cza podpisywanie komend kick. W³±czenie tej opcji powoduje dodawanie nicka osoby @@ -5480,7 +5579,7 @@ CHAN_HELP_SET_SIGNKICK %R%S HELP LEVELS CHAN_HELP_SET_XOP - Sk³adnia: SET kana³ XOP {ON | OFF} + Sk³adnia: %s kana³ XOP {ON | OFF} W³±cza lub wy³±cza system list xOP dla kana³u. Kiedy XOP zostanie w³±czony przyznawanie uprawnieñ @@ -5503,7 +5602,7 @@ CHAN_HELP_SET_XOP polecenia LEVELS. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -5526,7 +5625,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Sk³adnia: SET kana³ OPNOTICE {ON | OFF} + Sk³adnia: %s kana³ OPNOTICE {ON | OFF} W³±cza lub wy³±cza opcjê OPNOTICE dla kana³u. Kiedy ta opcja jest w³±czona, %S bêdzie @@ -6101,12 +6200,6 @@ CHAN_SERVADMIN_HELP_DROP Usuwa wskazany kana³. Tylko administratorzy serwisów mog± usun±æ kana³, którego nie s± w³a¶cicielami. -CHAN_SERVADMIN_HELP_SET - - Administratorzy serwisów mog± ustawiæ kana³owi - opcjê NOEXPIRE, która zapobiega wyga¶niêciu - kana³u je¶li nie jest on u¿ywany. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Sk³adnia: SET kana³ NOEXPIRE {ON | OFF} @@ -6444,8 +6537,8 @@ OPER_HELP_CMD_KILLCLONES OPER_HELP_CMD_AKILL AKILL Zarz±dza list± AKILL -OPER_HELP_CMD_SGLINE - SGLINE Zarz±dza list± SGLINE +OPER_HELP_CMD_SNLINE + SNLINE Zarz±dza list± SNLINE OPER_HELP_CMD_SQLINE SQLINE Zarz±dza list± SQLINE @@ -6647,19 +6740,19 @@ OPER_HELP_AKILL AKILL CLEAR usuwa wszystkie wpisy z listy AKILL. -OPER_HELP_SGLINE - Sk³adnia: SGLINE ADD [+czas-trwania] maska powód - SGLINE DEL {maska | numer-wpisu | lista} - SGLINE LIST [maska | lista] - SGLINE VIEW [maska | lista] - SGLINE CLEAR +OPER_HELP_SNLINE + Sk³adnia: SNLINE ADD [+czas-trwania] maska powód + SNLINE DEL {maska | numer-wpisu | lista} + SNLINE LIST [maska | lista] + SNLINE VIEW [maska | lista] + SNLINE CLEAR - Pozwala operatorom serwisów na zarz±dzanie list± SGLINE. + Pozwala operatorom serwisów na zarz±dzanie list± SNLINE. Je¶li u¿ytkownik z realname pasuj±cym do maski na li¶cie pod³±czy siê do sieci serwisy natychmiast go roz³±cz±. - SGLINE ADD dodaje wskazan± maskê realname oraz - powód (który musi zostaæ podany) na listê SGLINE. + SNLINE ADD dodaje wskazan± maskê realname oraz + powód (który musi zostaæ podany) na listê SNLINE. Podaj±c czas mo¿na stosowaæ jednostki: s dla sekund, m dla minut, h dla godzin oraz d dla dni. Kombinacja tych jednostek nie jest mo¿liwa. Domy¶ln± @@ -6671,22 +6764,22 @@ OPER_HELP_SGLINE Uwaga: realname mo¿e zawieraæ spacje, dlatego separatorem pomiêdzy mask± i powodem jest dwukropek. - SGLINE DEL usuwa wskazane wpisy z listy SGLINE. + SNLINE DEL usuwa wskazane wpisy z listy SNLINE. Jako argument przyjmuje maskê, numer wpisu lub listê (przyk³ad poni¿ej dla polecenia LIST). - SGLINE LIST wy¶wietla zawarto¶æ listy SGLINE. Je¶li + SNLINE LIST wy¶wietla zawarto¶æ listy SNLINE. Je¶li zostanie podana maska tylko pasuj±ce wpisy zostan± pokazane. Mo¿na tak¿e u¿yæ listy, przyk³ad: - SGLINE LIST 2-5,7-9 + SNLINE LIST 2-5,7-9 Listuje wpisy od 2 do 5 oraz od 7 do 9. - SGLINE VIEW zwraca wiêcej szczegó³ów ni¿ SGLINE LIST. - Wy¶wietla informacje o dodaj±cym SGLINE, datê dodania, + SNLINE VIEW zwraca wiêcej szczegó³ów ni¿ SNLINE LIST. + Wy¶wietla informacje o dodaj±cym SNLINE, datê dodania, datê wyga¶niêcia, maskê oraz powód. - SGLINE CLEAR usuwa wszystkie wpisy z listy. + SNLINE CLEAR usuwa wszystkie wpisy z listy. OPER_HELP_SQLINE Sk³adnia: SQLINE ADD [+czas-trwania] maska powód @@ -379,6 +379,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Você é agora um membro do grupo %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY senha @@ -811,9 +819,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER %d nicks no grupo. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expira em %s) + %s (expira em %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -863,18 +871,15 @@ NICK_SENDPASS_UNAVAILABLE Comando SENDPASS não disponível: modo de encriptação ativado. NICK_SENDPASS_SUBJECT Senha do nick (%s) -NICK_SENDPASS_HEAD - Olá, -NICK_SENDPASS_LINE_1 - Você pediu para que a senha do nick %s fosse enviada por e-mail. -NICK_SENDPASS_LINE_2 - A senha é %s. Por motivos de segurança, recomendamos que você mude sua senha após ler este e-mail. -NICK_SENDPASS_LINE_3 - Se você não souba porque este e-mail lhe foi enviado, por favor ignore-o. -NICK_SENDPASS_LINE_4 - NÃO RESPONDA A ESTE E-MAIL! -NICK_SENDPASS_LINE_5 - Administradores %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Senha para %s foi enviada. @@ -888,9 +893,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -935,18 +939,15 @@ NICK_ENTER_REG_CODE O passcode foi enviado para %s, por favor digite %R%s confirm <passcode> para completar o registro. NICK_REG_MAIL_SUBJECT Registro de nick (%s) -NICK_REG_MAIL_HEAD - Olá, -NICK_REG_MAIL_LINE_1 - Você solicitou o registro do seguinte nick: %s. -NICK_REG_MAIL_LINE_2 - Por favor digite %R%s confirm %s para completar o registro. -NICK_REG_MAIL_LINE_3 - Se você não sabe porque este e-mail lhe foi enviado, por favor ignore-o com sigilo. -NICK_REG_MAIL_LINE_4 - POR FAVOR NÃO RESPONDA A ESTE E-MAIL! -NICK_REG_MAIL_LINE_5 - Administradores %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Passcode para %s é %s. NICK_FORCE_REG @@ -1047,6 +1048,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1096,6 +1099,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED O canal %s foi desregistrado. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET canal opções parâmetros @@ -2010,12 +2041,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail responses MEMO_MAIL_SUBJECT Novo memo -MEMO_MAIL_TEXT1 - Olá %s -MEMO_MAIL_TEXT2 - Você recebeu um novo memo de %s. Este é seu memo número %d. -MEMO_MAIL_TEXT3 - Mensagem do memo: +NICK_MAIL_TEXT + Hi %s + + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s # RSEND responses MEMO_RSEND_PLEASE_WAIT @@ -2516,22 +2549,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Tempo atual de expiração de akill: 1 minuto OPER_STATS_AKILL_EXPIRE_NONE Tempo atual de expiração de akill: Não expira -OPER_STATS_SGLINE_COUNT - Número atual de SGLINEs: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Tempo atual de expiração de SGLINE: %d dias -OPER_STATS_SGLINE_EXPIRE_DAY - Tempo atual de expiração de SGLINE: 1 dia -OPER_STATS_SGLINE_EXPIRE_HOURS - Tempo atual de expiração de SGLINE: %d horas -OPER_STATS_SGLINE_EXPIRE_HOUR - Tempo atual de expiração de SGLINE: 1 hora -OPER_STATS_SGLINE_EXPIRE_MINS - Tempo atual de expiração de SGLINE: %d minutos -OPER_STATS_SGLINE_EXPIRE_MIN - Tempo atual de expiração de SGLINE: 1 minuto -OPER_STATS_SGLINE_EXPIRE_NONE - Tempo atual de expiração de SGLINE: Não expira +OPER_STATS_SNLINE_COUNT + Número atual de SNLINEs: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Tempo atual de expiração de SNLINE: %d dias +OPER_STATS_SNLINE_EXPIRE_DAY + Tempo atual de expiração de SNLINE: 1 dia +OPER_STATS_SNLINE_EXPIRE_HOURS + Tempo atual de expiração de SNLINE: %d horas +OPER_STATS_SNLINE_EXPIRE_HOUR + Tempo atual de expiração de SNLINE: 1 hora +OPER_STATS_SNLINE_EXPIRE_MINS + Tempo atual de expiração de SNLINE: %d minutos +OPER_STATS_SNLINE_EXPIRE_MIN + Tempo atual de expiração de SNLINE: 1 minuto +OPER_STATS_SNLINE_EXPIRE_NONE + Tempo atual de expiração de SNLINE: Não expira OPER_STATS_SQLINE_COUNT Número atual de SQLINEs: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2657,46 +2690,46 @@ OPER_AKILL_CLEAR OPER_CHANKILL_SYNTAX CHANKILL [+tempo] {#canal} [motivo] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+tempo] {máscara | lista}[:motivo]] -OPER_SGLINE_UNSUPPORTED - Desculpe, SGLINE não está disponível nesta Rede. -OPER_SGLINE_EXISTS - %s já existe na lista de SGLINE. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+tempo] {máscara | lista}[:motivo]] +OPER_SNLINE_UNSUPPORTED + Desculpe, SNLINE não está disponível nesta Rede. +OPER_SNLINE_EXISTS + %s já existe na lista de SNLINE. +OPER_SNLINE_ALREADY_COVERED %s já está coberto por %s. -OPER_SGLINE_REACHED_LIMIT - Desculpe, você pode ter apenas %d SGLINEs. -OPER_SGLINE_ADDED - %s adicionado à lista de SGLINE. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Desculpe, você pode ter apenas %d SNLINEs. +OPER_SNLINE_ADDED + %s adicionado à lista de SNLINE. +OPER_SNLINE_CHANGED Tempo de expiração para %s aterado. -OPER_SGLINE_NOT_FOUND - %s não encontrado na lista de SGLINE. -OPER_SGLINE_NO_MATCH - Nenhum resultado equivalente na lista de SGLINE. -OPER_SGLINE_DELETED - %s removido da lista de SGLINE. -OPER_SGLINE_DELETED_ONE - Removida 1 entrada da lista de SGLINE. -OPER_SGLINE_DELETED_SEVERAL - Removidas %d entradas da lista de SGLINE. -OPER_SGLINE_LIST_EMPTY - A lista de SGLINE está vazia. -OPER_SGLINE_LIST_HEADER - Lista de SGLINE atual: +OPER_SNLINE_NOT_FOUND + %s não encontrado na lista de SNLINE. +OPER_SNLINE_NO_MATCH + Nenhum resultado equivalente na lista de SNLINE. +OPER_SNLINE_DELETED + %s removido da lista de SNLINE. +OPER_SNLINE_DELETED_ONE + Removida 1 entrada da lista de SNLINE. +OPER_SNLINE_DELETED_SEVERAL + Removidas %d entradas da lista de SNLINE. +OPER_SNLINE_LIST_EMPTY + A lista de SNLINE está vazia. +OPER_SNLINE_LIST_HEADER + Lista de SNLINE atual: Núm Máscara Motivo -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Lista de SGLINE atual: +OPER_SNLINE_VIEW_HEADER + Lista de SNLINE atual: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (por %s em %s; %s) %s -OPER_SGLINE_CLEAR - A lista de SGLINE foi apagada. +OPER_SNLINE_CLEAR + A lista de SNLINE foi apagada. # SZLINE responses OPER_SQLINE_SYNTAX @@ -3310,6 +3343,8 @@ NICK_HELP_CMD_REGISTER REGISTER Registra um nick NICK_HELP_CMD_GROUP GROUP Se junta a um grupo +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Identifica seu nick com sua senha NICK_HELP_CMD_ACCESS @@ -3440,6 +3475,15 @@ NICK_HELP_GROUP Atenção: todos os nicks do grupo terão a mesma senha. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Sintaxe: IDENTIFY senha @@ -3500,25 +3544,39 @@ NICK_HELP_ACCESS ACCESS LIST Mostra a lista de acesso atual. -NICK_HELP_SET +NICK_HELP_SET_HEAD Sintaxe: SET opção parâmetros Ajusta várias opções de nick. A opção pode ser: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Mostra o seu grupo nos Services +NICK_HELP_CMD_SET_PASSWORD PASSWORD Ajusta a senha do seu nick +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Ajusta a linguagem dos Services quando mensagens são enviadas à você +NICK_HELP_CMD_SET_URL URL Associa um endereço URL com seu nick +NICK_HELP_CMD_SET_EMAIL EMAIL Associa um endereço de e-mail ao seu nick +NICK_HELP_CMD_SET_ICQ ICQ Associa um número de ICQ ao seu nick +NICK_HELP_CMD_SET_GREET GREET Associa uma mensgem de entrada ao seu nick +NICK_HELP_CMD_SET_KILL KILL Ativa/Desativa a proteção de kill para o seu nick +NICK_HELP_CMD_SET_SECURE SECURE Ativa/Desativa os recursos de segurança para o seu nick +NICK_HELP_CMD_SET_PRIVATE PRIVATE Previne seu nick de aparecer em um %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE Esconde certas informações sobre seu nick +NICK_HELP_CMD_SET_MSG MSG Altera o método de comunicação dos Services +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Para usar este comando, você deve primeiro se identificar com sua senha (%R%S HELP IDENTIFY para maiores @@ -3641,26 +3699,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -3975,7 +4047,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Administradores de Services podem usar o parâmetro ALL com qualquer nick. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Sintaxe: LIST padrão [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4078,6 +4151,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Registra um canal CHAN_HELP_CMD_SET SET Ajusta as opções e informações do canal +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4180,7 +4255,15 @@ CHAN_HELP_DROP Cancela o registro do canal. So poderá ser usado pelo fundador do canal. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Sintaxe: SET canal opção parâmetros Permite ao fundador do canal ajustar as várias opções do @@ -4188,39 +4271,62 @@ CHAN_HELP_SET Opções disponíveis: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Ajusta o fundador do canal +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Ajusta o sucessor do canal +CHAN_HELP_CMD_SET_DESC DESC Ajusta a descrição do canal +CHAN_HELP_CMD_SET_URL URL Associa uma URL a um canal +CHAN_HELP_CMD_SET_EMAIL EMAIL Associa um E-mail a um canal +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Ajusta a mensagem que deve ser mandada aos usuários quando eles entram no canal +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Ajusta como os Services devem fazer o ban +CHAN_HELP_CMD_SET_MLOCK MLOCK Liga ou desliga a trava dos modos do canal +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Mantem o tópico quando o canal não está em uso +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK O tópico pode ser mudado apenas com o comando TOPIC +CHAN_HELP_CMD_SET_PEACE PEACE Regula o uso de comandos críticos +CHAN_HELP_CMD_SET_PRIVATE PRIVATE Esconde o canal do comando LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Acesso restrito ao canal +CHAN_HELP_CMD_SET_SECURE SECURE Ativa os recursos de segurança do %S +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Controle rigoroso do status de OP +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Controle rigoroso do status de Fundador do Canal +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK Assinatura dos kicks feitos pelo comando KICK +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE Envia uma notice quando os comandos OP/DEOP são usados +CHAN_HELP_CMD_SET_XOP XOP Altera o sistema de privilégio de usuário - PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_PERSIST + PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Digite %R%S HELP SET opção para maiores informações sobre uma opção em particular. CHAN_HELP_SET_FOUNDER - Sintaxe: SET canal FOUNDER nick + Sintaxe: %s canal FOUNDER nick Muda o fundador do canal. O novo nick deve estar registrado. CHAN_HELP_SET_SUCCESSOR - Sintaxe: SET canal SUCCESSOR nick + Sintaxe: %s canal SUCCESSOR nick Altera o sucessor de um canal. Se o nick do founder expirar ou for dropado enquanto o canal ainda estiver registrado, @@ -4230,13 +4336,13 @@ CHAN_HELP_SET_SUCCESSOR sido ajustado. O novo nick deverá estar registrado. CHAN_HELP_SET_DESC - Sintaxe: SET canal DESC descrição + Sintaxe: %s canal DESC descrição Ajusta a descrição para o canal, que são mostradas com os comandos LIST e INFO. CHAN_HELP_SET_URL - Sintaxe: SET canal URL [url] + Sintaxe: %s canal URL [url] Associa uma URL ao canal. Esta URL será mostrada sempre que alguem solicitar informação sobre o canal @@ -4244,7 +4350,7 @@ CHAN_HELP_SET_URL apaga qualquer URL atualmente designada para o canal. CHAN_HELP_SET_EMAIL - Sintaxe: SET canal EMAIL [endereço] + Sintaxe: %s canal EMAIL [endereço] Associa um endereço de e-mail fornecido ao canal. Este endereço será mostrado sempre que alguem solicitar @@ -4253,7 +4359,7 @@ CHAN_HELP_SET_EMAIL do canal. CHAN_HELP_SET_ENTRYMSG - Sintaxe: SET canal ENTRYMSG [mensagem] + Sintaxe: %s canal ENTRYMSG [mensagem] Ajusta a mensagem na qual será enviada via /notice para os usuários quando eles entrarem no canal. Se nenhum @@ -4261,7 +4367,7 @@ CHAN_HELP_SET_ENTRYMSG ao se entrar no canal. CHAN_HELP_SET_BANTYPE - Sintaxe: SET canal BANTYPE tipo-de-ban + Sintaxe: %s canal BANTYPE tipo-de-ban Seleciona o tipo de ban que será usado sempre que os Services precisarem banir alguém do seu canal. @@ -4274,7 +4380,7 @@ CHAN_HELP_SET_BANTYPE 3: ban na forma *!*user@*.domain CHAN_HELP_SET_KEEPTOPIC - Sintaxe: SET canal KEEPTOPIC {ON|OFF} + Sintaxe: %s canal KEEPTOPIC {ON|OFF} Ativa ou desativa a opção de retenção de tópico para um canal. Quando a retenção de tópico está acionada, @@ -4283,7 +4389,7 @@ CHAN_HELP_SET_KEEPTOPIC restaurado na próxima vez que o canal for reutilizado. CHAN_HELP_SET_TOPICLOCK - Sintaxe: SET canal TOPICLOCK {ON|OFF} + Sintaxe: %s canal TOPICLOCK {ON|OFF} Ativa ou desativa a opção de trava do tópico de um canal. Quando a trava do tópico está ativada, o %S não @@ -4291,7 +4397,7 @@ CHAN_HELP_SET_TOPICLOCK TOPIC. CHAN_HELP_SET_MLOCK - Sintaxe: SET canal MLOCK modos + Sintaxe: %s canal MLOCK modos Ajusta o parâmetro da trava do modo para um canal. O %S permite que você defina certos modos no canal @@ -4329,7 +4435,7 @@ CHAN_HELP_SET_MLOCK ficam livres para ser ativos ou desativos. CHAN_HELP_SET_PEACE - Sintaxe: SET canal PEACE {ON | OFF} + Sintaxe: %s canal PEACE {ON | OFF} Ativa ou destiva a opção peace para um canal. Quando peace está ativada, um usuário não poderá kickar, @@ -4337,21 +4443,21 @@ CHAN_HELP_SET_PEACE nível superior ou igual ao seu via comandos do %S. CHAN_HELP_SET_PRIVATE - Sintaxe: SET canal PRIVATE {ON|OFF} + Sintaxe: %s canal PRIVATE {ON|OFF} Ativa ou desativa a opção private para um canal. Quando private está ativada, um %R%S LIST não irá incluir o canal em qualquer listagem. CHAN_HELP_SET_RESTRICTED - Sintaxe: SET canal RESTRICTED {ON|OFF} + Sintaxe: %s canal RESTRICTED {ON|OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Sintaxe: SET canal SECURE {ON|OFF} + Sintaxe: %s canal SECURE {ON|OFF} Ativa ou desativa os recursos de segurança do %S para um canal. Quando o SECURE estiver ativo, somente @@ -4360,14 +4466,14 @@ CHAN_HELP_SET_SECURE controlado pela lista de acesso. CHAN_HELP_SET_SECUREOPS - Sintaxe: SET canal SECUREOPS {ON|OFF} + Sintaxe: %s canal SECUREOPS {ON|OFF} Ativa ou desativa a opção de segurança de ops para um canal. Quando secure ops estiver ativada, os usuários que não estiverem na lista de acesso não poderão ter o status de OP. CHAN_HELP_SET_SECUREFOUNDER - Sintaxe: SET canal SECUREFOUNDER {ON | OFF} + Sintaxe: %s canal SECUREFOUNDER {ON | OFF} Ativa ou desativa a opção secure founder para um canal. Quando o secure founder está ligado, apenas o verdadeiro founder @@ -4375,7 +4481,7 @@ CHAN_HELP_SET_SECUREFOUNDER successor, e não aqueles que estiverem identificados no %S. CHAN_HELP_SET_SIGNKICK - Sintaxe: SET canal SIGNKICK {ON | LEVEL | OFF} + Sintaxe: %s canal SIGNKICK {ON | LEVEL | OFF} Habilita ou desabilita a assinatura nos kicks para um canal. Quando o SIGNKICK está habilitado, kicks através @@ -4387,7 +4493,7 @@ CHAN_HELP_SET_SIGNKICK motivo. Veja %R%S HELP LEVELS para maiores informações. CHAN_HELP_SET_XOP - Sintaxe: SET canal XOP {ON | OFF} + Sintaxe: %s canal XOP {ON | OFF} Ativa ou desativa o sistema de listas xOP para um canal. Quando XOP está ativado, você deve usar os comandos @@ -4409,7 +4515,7 @@ CHAN_HELP_SET_XOP de acesso não causa problemas. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4432,7 +4538,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Sintaxe: SET canal OPNOTICE {ON | OFF} + Sintaxe: %s canal OPNOTICE {ON | OFF} Ativa e desativa a opção Op-notice para um canal. Quando Op-notice estiver ativado, o %S enviará uma notice para @@ -4983,13 +5089,6 @@ CHAN_SERVADMIN_HELP_DROP Cancela o registro de um canal. Somente Administradores dos Services podem cancelar canais que pertencem a outros usuários. -CHAN_SERVADMIN_HELP_SET - - Administradores dos Services também podem ajustar a opção - NOEXPIRE, fazendo com que canais sejam impedidos de ter - seu registro expirado. Services Operators ainda - podem ajustar opções para qualquer canal de outros usuários. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Sintaxe: SET canal NOEXPIRE {ON | OFF} @@ -5303,8 +5402,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Derruba todos os usuários de um mesmo host OPER_HELP_CMD_AKILL AKILL Manipula a lista de AKILL -OPER_HELP_CMD_SGLINE - SGLINE Manipula a lista de SGLINE +OPER_HELP_CMD_SNLINE + SNLINE Manipula a lista de SNLINE OPER_HELP_CMD_SQLINE SQLINE Manipula a lista de SQLINE OPER_HELP_CMD_SZLINE @@ -5501,50 +5600,50 @@ OPER_HELP_AKILL AKILL CLEAR apaga todas as entradas da lista de AKILL. -OPER_HELP_SGLINE - Sintaxe: SGLINE ADD [+tempo] máscara:motivo - SGLINE DEL {máscara | entrada | lista-entradas} - SGLINE LIST [máscara | lista-entradas] - SGLINE VIEW [máscara | lista-entradas] - SGLINE CLEAR +OPER_HELP_SNLINE + Sintaxe: SNLINE ADD [+tempo] máscara:motivo + SNLINE DEL {máscara | entrada | lista-entradas} + SNLINE LIST [máscara | lista-entradas] + SNLINE VIEW [máscara | lista-entradas] + SNLINE CLEAR Permite que Operadores dos Services manipulem a lista de - SGLINE. Se um usuário que tenta conectar possui um realname - previsto na lista de SGLINE, os Services não permitirão que + SNLINE. Se um usuário que tenta conectar possui um realname + previsto na lista de SNLINE, os Services não permitirão que ele continue sua sessão de IRC. - SGLINE ADD adiciona uma máscara realname na lista de SGLINE + SNLINE ADD adiciona uma máscara realname na lista de SNLINE para um dado motivo (deve ser fornecido). Opcionalmente, um tempo pode ser fornecido. O tempo precede a máscara e é especificado como um número inteiro seguido por uma das seguintes unidades: d (dias), h (horas) ou m (minutos). Combinações (como 1h30m) não são permitidas. Se uma unidade específica não é incluída, o padrão é em dias (assim, +30 - significa 30 dias). Para adicionar um SGLINE que não expira, + significa 30 dias). Para adicionar um SNLINE que não expira, use +0. Se a máscara de realname a ser adicionada começar com - um +, o tempo do SGLINE deve ser fornecido, mesmo se esse tempo - for igual ao padrão. O tempo atual de expiração de SGLINE pode ser + um +, o tempo do SNLINE deve ser fornecido, mesmo se esse tempo + for igual ao padrão. O tempo atual de expiração de SNLINE pode ser encontrado com o comando STATS AKILL. Nota: devido ao fato da máscara de realname poder conter espaços, o separador entre ela e o motivo é um sinal de dois-pontos. - SGLINE DEL remove uma dada máscara da lista de SGLINE, se ela + SNLINE DEL remove uma dada máscara da lista de SNLINE, se ela estiver presente. Se uma lista de números de entrada for fornecida, essas entradas serão apagadas. (Veja o exemplo para LIST abaixo.) - SGLINE LIST mostra a lista de SGLINE atual. + SNLINE LIST mostra a lista de SNLINE atual. Se uma máscara for fornecida, apenas as entradas que combinarem com a máscara serão exibidas. Se uma lista de números de entrada for fornecida, apenas essas entradas serão exibidas; por exemplo: - SGLINE LIST 2-5,7-9 - Lista as entradas de SGLINE numeradas de 2 a 5 e de 7 a 9. + SNLINE LIST 2-5,7-9 + Lista as entradas de SNLINE numeradas de 2 a 5 e de 7 a 9. - SGLINE VIEW é uma versão mais detalhada do SGLINE LIST, - e mostrará quem adicionou o SGLINE, a data em que foi adicionado, + SNLINE VIEW é uma versão mais detalhada do SNLINE LIST, + e mostrará quem adicionou o SNLINE, a data em que foi adicionado, e quando irá expirar, como também a máscara realname e o motivo. - SGLINE CLEAR apaga todas as entradas da lista de SGLINE. + SNLINE CLEAR apaga todas as entradas da lista de SNLINE. OPER_HELP_SQLINE Sintaxe: SQLINE ADD [+tempo] máscara motivo @@ -369,6 +369,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED Âû óñïåøíî âíåñåíû â ãðóïïó %s. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY ïàðîëü @@ -792,9 +800,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER Êîëè÷åñòâî íèêîâ â ãðóïïå: %d NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (èñòåêàåò %s) + %s (èñòåêàåò %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -845,18 +853,15 @@ NICK_SENDPASS_UNAVAILABLE Êîìàíäà SENDPASS íåäîñòóïíà, òàê êàê âêëþ÷åíî øèôðîâàíèå ïàðîëåé. NICK_SENDPASS_SUBJECT Ïàðîëü äëÿ íèêà %s -NICK_SENDPASS_HEAD - Äîáðîãî âðåìåíè ñóòîê, ìíîãîóâàæàåìûé/àÿ! -NICK_SENDPASS_LINE_1 - Áûë ïîëó÷åí çàïðîñ íà âîññòàíîâëåíèå ïàðîëÿ îò âàøåãî íèêà %s -NICK_SENDPASS_LINE_2 - Âàø ïàðîëü %s * Äëÿ áîëüøåé áåçîïàñíîñòè, ðåêîìåíäóåòñÿ èçìåíèòü åãî êàê ìîæíî ñêîðåå. -NICK_SENDPASS_LINE_3 - Åñëè âû íå çàïðàøèâàëè ýòî ïèñüìî, ïðîñòî ïðîèãíîðèðóéòå åãî. -NICK_SENDPASS_LINE_4 - ÏÎÆÀËÓÉÑÒÀ, ÍÅ ÎÒÂÅ×ÀÉÒÅ ÍÀ ÝÒÎ ÏÈÑÜÌÎ! -NICK_SENDPASS_LINE_5 - Àäìèíèñòðàöèÿ ñåòè %s. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK Ïàðîëü äëÿ íèêà %s áûë âûñëàí íà åãî email-àäðåñ. @@ -870,9 +875,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -917,18 +921,15 @@ NICK_ENTER_REG_CODE Auth-êîä áûë âûñëàí íà %s, äëÿ çàâåðøåíèÿ ðåãèñòðàöèè èñïîëüçóéòå êîìàíäó %R%s confirm auth-êîä NICK_REG_MAIL_SUBJECT Ðåãèñòðàöèÿ íèêà %s -NICK_REG_MAIL_HEAD - Äîáðîãî âðåìåíè ñóòîê, ìíîãîóâàæàåìûé/àÿ! -NICK_REG_MAIL_LINE_1 - Âû çàïðîñèëè ðåãèñòðàöèþ íèêà %s -NICK_REG_MAIL_LINE_2 - Äëÿ çàâåðøåíèÿ ïðîöåññà ðåãèñòðàöèè íèêà, âîñïîëüçóéòåñü êîìàíäîé %R%s CONFIRM %s -NICK_REG_MAIL_LINE_3 - Åñëè âû íå çàïðàøèâàëè ýòî ïèñüìî - ïðîñòî ïðîèãíîðèðóéòå åãî. -NICK_REG_MAIL_LINE_4 - ÏÎÆÀËÓÉÑÒÀ, ÍÅ ÎÒÂÅ×ÀÉÒÅ ÍÀ ÝÒÎ ÏÈÑÜÌÎ! -NICK_REG_MAIL_LINE_5 - Àäìèíèñòðàöèÿ ñåòè %s. +NICK_REG_MAIL + Hi, + + You have requested to register the nickname %s on %s. + Please type " %R%s confirm %s " to complete registration. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_GETPASS_PASSCODE_IS Ïàðîëü äëÿ íèêà %s - %s. NICK_FORCE_REG @@ -1028,6 +1029,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1075,6 +1078,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED Êàíàë %s óäàëåí èç áàçû äàííûõ. +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET #êàíàë îïöèÿ ïàðàìåòð @@ -1987,13 +2018,15 @@ MEMO_INFO_X_NOTIFY_SIGNON # Memo2Mail responses MEMO_MAIL_SUBJECT Íîâîå ìåìî-ñîîáùåíèå -MEMO_MAIL_TEXT1 - Çäðàñòâóéòå %s. -MEMO_MAIL_TEXT2 - Âû ïîëó÷èëè íîâîå ìåìî-ñîîáùåíèå îò %s. Íîìåð ñîîáùåíèÿ: %d. -MEMO_MAIL_TEXT3 - Òåêñò ñîîáùåíèÿ: +NICK_MAIL_TEXT + Hi %s + You've just received a new memo from %s. This is memo number %d. + + Memo text: + + %s + # RSEND responses MEMO_RSEND_PLEASE_WAIT Ïîæàëóéñòà, ïîäîæäèòå %d ñåêóíä ïåðåä ïîâòîðíûì èñïîëüçîâàíèåì êîìàíäû RSEND. @@ -2490,22 +2523,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Âðåìÿ èñòå÷åíèÿ AKILL'à ïî-óìîë÷àíèþ : 1 ìèíóòà OPER_STATS_AKILL_EXPIRE_NONE Âðåìÿ èñòå÷åíèÿ AKILL'à ïî-óìîë÷àíèþ : íèêîãäà -OPER_STATS_SGLINE_COUNT - Òåêóùåå êîëè÷åñòâî SGLINE'îâ : %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : %d äíåé -OPER_STATS_SGLINE_EXPIRE_DAY - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : 1 äåíü -OPER_STATS_SGLINE_EXPIRE_HOURS - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : %d ÷àñîâ -OPER_STATS_SGLINE_EXPIRE_HOUR - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : 1 ÷àñ -OPER_STATS_SGLINE_EXPIRE_MINS - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : %d ìèíóò -OPER_STATS_SGLINE_EXPIRE_MIN - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : 1 ìèíóòà -OPER_STATS_SGLINE_EXPIRE_NONE - Âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ : íèêîãäà +OPER_STATS_SNLINE_COUNT + Òåêóùåå êîëè÷åñòâî SNLINE'îâ : %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : %d äíåé +OPER_STATS_SNLINE_EXPIRE_DAY + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : 1 äåíü +OPER_STATS_SNLINE_EXPIRE_HOURS + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : %d ÷àñîâ +OPER_STATS_SNLINE_EXPIRE_HOUR + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : 1 ÷àñ +OPER_STATS_SNLINE_EXPIRE_MINS + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : %d ìèíóò +OPER_STATS_SNLINE_EXPIRE_MIN + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : 1 ìèíóòà +OPER_STATS_SNLINE_EXPIRE_NONE + Âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ : íèêîãäà OPER_STATS_SQLINE_COUNT Òåêóùåå êîëè÷åñòâî SQLINE'îâ : %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2627,46 +2660,46 @@ OPER_AKILL_CLEAR Ñïèñîê AKILL'îâ ïîëíîñòüþ î÷èùåí. OPER_CHANKILL_SYNTAX CHANKILL [+ñðîê_èñòå÷åíèÿ] {#êàíàë} [ïðè÷èíà] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD|DEL|LIST|VIEW|CLEAR} [[+ñðîê_èñòå÷åíèÿ] {ìàñêà | íîìåð_çàïèñè}[:ïðè÷èíà]] -OPER_SGLINE_UNSUPPORTED - SGLINE-âîçìîæíîñòè ñåðâèñîâ â âàøåé ñåòè íåäîñòóïíû. -OPER_SGLINE_EXISTS - Çàïèñü âèäà %s óæå ñîäåðæèòñÿ â ñïèñêå SGLINE'îâ. -OPER_SGLINE_ALREADY_COVERED - Óêàçàííàÿ ìàñêà âèäà %s ñîâïàäàåò ñ îäíîé èç ìàñîê â ñïèñêå SGLINE'îâ: %s. -OPER_SGLINE_REACHED_LIMIT - Êîëè÷åñòâî çàïèñåé â SGLINE-ñïèñêå íå ìîæåò ïðåâûøàòü %d. -OPER_SGLINE_ADDED - Çàïèñü âèäà %s óñïåøíî äîáàâëåíà â ñïèñîê SGLINE'îâ. -OPER_SGLINE_CHANGED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD|DEL|LIST|VIEW|CLEAR} [[+ñðîê_èñòå÷åíèÿ] {ìàñêà | íîìåð_çàïèñè}[:ïðè÷èíà]] +OPER_SNLINE_UNSUPPORTED + SNLINE-âîçìîæíîñòè ñåðâèñîâ â âàøåé ñåòè íåäîñòóïíû. +OPER_SNLINE_EXISTS + Çàïèñü âèäà %s óæå ñîäåðæèòñÿ â ñïèñêå SNLINE'îâ. +OPER_SNLINE_ALREADY_COVERED + Óêàçàííàÿ ìàñêà âèäà %s ñîâïàäàåò ñ îäíîé èç ìàñîê â ñïèñêå SNLINE'îâ: %s. +OPER_SNLINE_REACHED_LIMIT + Êîëè÷åñòâî çàïèñåé â SNLINE-ñïèñêå íå ìîæåò ïðåâûøàòü %d. +OPER_SNLINE_ADDED + Çàïèñü âèäà %s óñïåøíî äîáàâëåíà â ñïèñîê SNLINE'îâ. +OPER_SNLINE_CHANGED Ñðîê èñòå÷åíèÿ çàïèñè %s óñïåøíî èçìåíåí. -OPER_SGLINE_NOT_FOUND - Çàïèñü âèäà %s â ñïèñêå SGLINE'îâ íå îáíàðóæåíà. -OPER_SGLINE_NO_MATCH +OPER_SNLINE_NOT_FOUND + Çàïèñü âèäà %s â ñïèñêå SNLINE'îâ íå îáíàðóæåíà. +OPER_SNLINE_NO_MATCH Ñîâïàäàþùèõ çàïèñåé íå îáíàðóæåíî. -OPER_SGLINE_DELETED - Çàïèñü âèäà %s óñïåøíî óäàëåíà èç ñïèñêà SGLINE'îâ. -OPER_SGLINE_DELETED_ONE - Óäàëåíà 1 çàïèñü èç ñïèêà SGLINE'îâ. -OPER_SGLINE_DELETED_SEVERAL - Óäàëåíî %d çàïèñåé èç ñïèñêà SGLINE'îâ. -OPER_SGLINE_LIST_EMPTY - Ñïèñîê SGLINE'îâ ïóñò. -OPER_SGLINE_LIST_HEADER - Òåêóùèé ñïèñîê SGLINE'îâ: +OPER_SNLINE_DELETED + Çàïèñü âèäà %s óñïåøíî óäàëåíà èç ñïèñêà SNLINE'îâ. +OPER_SNLINE_DELETED_ONE + Óäàëåíà 1 çàïèñü èç ñïèêà SNLINE'îâ. +OPER_SNLINE_DELETED_SEVERAL + Óäàëåíî %d çàïèñåé èç ñïèñêà SNLINE'îâ. +OPER_SNLINE_LIST_EMPTY + Ñïèñîê SNLINE'îâ ïóñò. +OPER_SNLINE_LIST_HEADER + Òåêóùèé ñïèñîê SNLINE'îâ: No. Ìàñêà Ïðè÷èíà -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Òåêóùèé ñïèñîê SGLINE'îâ: +OPER_SNLINE_VIEW_HEADER + Òåêóùèé ñïèñîê SNLINE'îâ: # íîìåð, ìàñêà, ñîçäàòåëü, êîãäà, èñòåêàåò, ïðè÷èíà -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (îò %s â %s; %s) %s -OPER_SGLINE_CLEAR - Ñïèñîê SGLINE'îâ ïîëíîñòüþ î÷èùåí. +OPER_SNLINE_CLEAR + Ñïèñîê SNLINE'îâ ïîëíîñòüþ î÷èùåí. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3305,6 +3338,8 @@ NICK_HELP_CMD_REGISTER REGISTER Ðåãèñòðàöèÿ íèêà NICK_HELP_CMD_GROUP GROUP Îáúåäèíåíèå íèêîâ â ãðóïïû +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Èäåíòèôèêàöèÿ ê íèêó â êà÷åñòâå âëàäåëüöà NICK_HELP_CMD_ACCESS @@ -3435,6 +3470,15 @@ NICK_HELP_GROUP íèêàê íåìîæåò. Ïðèìå÷àíèå 2: ó âñåõ íèêîâ â ãðóïïå - åäèíûé ïàðîëü. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Ñèíòàêñèñ: IDENTIFY ïàðîëü @@ -3495,26 +3539,40 @@ NICK_HELP_ACCESS ACCESS LIST âûâîäèò òåêóùèé ñïèñîê "äîâåðåííûõ" õîñòìàñîê. -NICK_HELP_SET +NICK_HELP_SET_HEAD Ñèíòàêñèñ: SET îïöèÿ ïàðàìåòðû Êîìàíäà SET ïîçâîëÿåò âàì íàñòðîèòü ðàçëè÷íûå îïöèè íèêà. Ñïèñîê îïöèé: +NICK_HELP_CMD_SET_DISPLAY DISPLAY óñòàíîâêà ãëàâíîãî íèêà ãðóïïû +NICK_HELP_CMD_SET_PASSWORD PASSWORD èçìåíåíèå òåêóùåãî ïàðîëÿ íà íèê +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE âûáîð ÿçûêà, ïîñðåäñòâîì êîòîðîãî ñåðâèñû áóäóò ñ âàìè îáùàòüñÿ +NICK_HELP_CMD_SET_URL URL óñòàíîâêà URL-àäðåñà íà íèê +NICK_HELP_CMD_SET_EMAIL EMAIL óñòàíîâêà email-àäðåñà íà íèê +NICK_HELP_CMD_SET_ICQ ICQ óñòàíîâêà ICQ-íîìåðà íà íèê +NICK_HELP_CMD_SET_GREET GREET óñòàíîâêà ïðèâåòñòâåííîãî ñîîáùåíèÿ +NICK_HELP_CMD_SET_KILL KILL àêòèâèðîâàíèå/äåàêòèâèðîâàíèå ðåæèìà çàùèòû +NICK_HELP_CMD_SET_SECURE SECURE àêòèâèðîâàíèå/äåàêòèâèðîâàíèå ðåæèìà áåçîïàñíîñòè +NICK_HELP_CMD_SET_PRIVATE PRIVATE ñêðûòèå âàøåãî íèêà â ñïèñêå íèêîâ ïî %R%S LIST +NICK_HELP_CMD_SET_HIDE HIDE ñêðûòèå ðàçëè÷íîé èíôîðìàöèè î âàøåì íèêå +NICK_HELP_CMD_SET_MSG MSG âûáîð ìåòîäà îáùåíèÿ ñåðâèñîâ ñ âàìè +NICK_HELP_CMD_SET_AUTOOP AUTOOP àêòèâèðîâàíèå/äåàêòèâèðîâàíèå àâòîñòàòóñà +NICK_HELP_SET_TAIL ×òîáû ïîëó÷èòü ñïðàâî÷íóþ èíôîðìàöèþ ïî îòäåëüíî âçÿòîé îïöèè âîñïîëüçóéòåñü êîìàíäîé %R%S HELP SET îïöèÿ @@ -3649,27 +3707,42 @@ NICK_HELP_SET_AUTOOP Óêàæèòå ON, åñëè õîòèòå ÷òî áû ñåðâèñû àâòîìàòè÷åñêè äàâàëè âàì ñòàòóñ ïðè âõîäå íà êàíàë. Ñîîòâåòñòâåííî OFF - äëÿ îòêëþ÷åíèÿ. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Ñèíòàêñèñ: SASET íèê îïöèÿ ïàðàìåòðû. Ïîçâîëÿåò Àäìèíèñòðàòîðàì ñåðâèñîâ íàñòðàèâàòü êàêèå-ëèáî îïöèè äëÿ óêàçàííîãî íèêà áåç èäåíòèôèêàöèè ê íåìó. Ñïèñîê îïöèè: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY óñòàíîâêà ãëàâíîãî íèêà ãðóïïû +NICK_HELP_CMD_SASET_PASSWORD PASSWORD èçìåíåíèå òåêóùåãî ïàðîëÿ íà íèê +NICK_HELP_CMD_SASET_URL URL óñòàíîâêà URL-àäðåñà íà íèê +NICK_HELP_CMD_SASET_EMAIL EMAIL óñòàíîâêà email-àäðåñà íà íèê +NICK_HELP_CMD_SASET_ICQ ICQ óñòàíîâêà ICQ-íîìåðà íà íèê +NICK_HELP_CMD_SASET_GREET GREET óñòàíîâêà ïðèâåòñòâåííîãî ñîîáùåíèÿ +NICK_HELP_CMD_SASET_KILL KILL àêòèâèðîâàíèå/äåàêòèâèðîâàíèå ðåæèìà çàùèòû +NICK_HELP_CMD_SASET_SECURE SECURE àêòèâèðîâàíèå/äåàêòèâèðîâàíèå ðåæèìà áåçîïàñíîñòè +NICK_HELP_CMD_SASET_PRIVATE PRIVATE ñêðûòèå íèêà â ñïèñêå íèêîâ ïî %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE ñêðûòèå ðàçëè÷íîé èíôîðìàöèè î íèêå +NICK_HELP_CMD_SASET_MSG MSG âûáîð ìåòîäà îáùåíèÿ ñåðâèñîâ ñ íèêîì +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE óñòàíîâêà íà íèê ò.í. ðåæèìà 'íå-èñòå÷åíèÿ' +NICK_HELP_CMD_SASET_AUTOOP AUTOOP àêòèâèðîâàíèå/äåàêòèâèðîâàíèå ðåæèìà àâòîñòàòóñà +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE âûáîð ÿçûêà, ïîñðåäñòâîì êîòîðîãî ñåðâèñû áóäóò ñ óêàçàííûì íèêîì. +NICK_HELP_SASET_TAIL ×òîáû ïîëó÷èòü ñïðàâî÷íóþ èíôîðìàöèþ ïî îòäåëüíî âçÿòîé îïöèè âîñïîëüçóéòåñü êîìàíäîé %R%S HELP SASET îïöèÿ @@ -4022,8 +4095,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Àäìèíèñòðàòîðû ñåðâèñîâ ìîãó èñïîëüçîâàòü ïàðàìåòð ALL äëÿ ëþáîãî - íèêà. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Ñèíòàêñèñ: LIST ìàñêà [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4138,6 +4211,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Ðåãèñòðàöèÿ êàíàëà CHAN_HELP_CMD_SET SET Íàñòðîéêà ðàçëè÷íûõ îïöèé êàíàëà +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4242,45 +4317,76 @@ CHAN_HELP_DROP Óäàëÿåò óêàçàííûé êàíàë èç áàçû äàííûõ ñåðâèñîâ. Èñïîëüçîâàòü DROP ìîæåò ëèøü âëàäåëåö êàíàëà. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Ñèíòàêñèñ: SET #êàíàë îïöèÿ ïàðàìåòð Ïîçâîëÿåò âëàäåëüöó êàíàëà ìåíÿòü ðàçëè÷íûå íàñòðîéêè êàíàëà. Äîñòóïíûå îïöèè: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER ñìåíà âëàäåëüöà êàíàëà +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR óñòàíîâêà íàñëåäíèêà êàíàëà +CHAN_HELP_CMD_SET_DESC DESC èçìåíåíèå îïèñàíèÿ êàíàëà +CHAN_HELP_CMD_SET_URL URL óñòàíîâêà URL-àäðåñà êàíàëà +CHAN_HELP_CMD_SET_EMAIL EMAIL óñòàíîâêà Email-àäðåñà êàíàëà +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG óñòàíîâêà àâòîñîîáùåíèÿ ïðè âõîäå íà êàíàë +CHAN_HELP_CMD_SET_BANTYPE BANTYPE óñòàíîâêà òèïà áàíà ñåðâèñàìè íà êàíàëå +CHAN_HELP_CMD_SET_MLOCK MLOCK áëîêèðîâêà îïðåäåëåííûõ ðåæèìîâ êàíàëà +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC àêòèâèðîâàíèå àâòîñîõðàíåíèÿ òîïèêà êàíàëà +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE àêòèâèðîâàíèå óâåäîìëåíèé îá èñïîëüçîâàíèè êîìàíä OP/DEOP +CHAN_HELP_CMD_SET_PEACE PEACE àêòèâèðîâàíèå ðåæèìà "ñïîêîéñòâèÿ" íà êàíàëå +CHAN_HELP_CMD_SET_PRIVATE PRIVATE ñêðûòèå êàíàëà â ñïèñêå êàíàëîâ âûâîäèìûõ ïî LIST +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED îãðàíè÷åíèå óðîâíÿ äîñòóïà íà êàíàë äî ïðîïèñàííûõ +CHAN_HELP_CMD_SET_SECURE SECURE äîïîëíèòåëüíûå âîçìîæíîñòè %S'à ïî áåçîïàñíîñòè +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS êîíòðîëü çà ïîëó÷åíèåì ñòàòóñà îïåðàòîðà êàíàëà +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER îãðàíè÷åíèå íà ïîëó÷åíèå ñòàòóñà âëàäåëüöà êàíàëà +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK íàñòðîéêà ðåæèìà "ïîäïèñàííûõ êèêîâ" +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK áëîêèðîâêà òîïèêà êàíàëà îò èçìåíåíèé åãî êåì-ëèáî +CHAN_HELP_CMD_SET_XOP XOP íàñòðîéêà ñèñòåìû ïðèâèëåãèé êàíàëà +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL Äëÿ áîëåå ïîäðîáíîé èíôîðìàöèè î êàêîé-ëèáî êîíêðåòíîé îïöèè, ñì. ñïðàâêó ïî %R%S HELP îïöèÿ CHAN_HELP_SET_FOUNDER - Ñèíòàêñèñ: SET #êàíàë FOUNDER íèê + Ñèíòàêñèñ: %s #êàíàë FOUNDER íèê Ïîçâîëÿåò ïåðåäàòü ïðàâà íà âëàäåíèå êàíàëîì äðóãîìó ïîëüçîâàòåëþ. Íèê íîâîãî âëàäåëüöà êàíàëà äîëæåí áûòü çàðåãèñòðèðîâàííûì. CHAN_HELP_SET_SUCCESSOR - Ñèíòàêñèñ: SET #êàíàë SUCCESSOR íèê + Ñèíòàêñèñ: %s #êàíàë SUCCESSOR íèê Ïîçâîëÿåò íàçíà÷èòü íàñëåäíèêà êàíàëà. Åñëè íèê òåêóùåãî âëàäåëüöà êàíàëà áóäåò óäàëåí ââèäó èñòå÷åíèÿ ñðîêà ðåãèñòðàöèè èëè ïî êàêèì @@ -4291,13 +4397,13 @@ CHAN_HELP_SET_SUCCESSOR äîëæåí áûòü çàðåãèñòðèðîâàííûì íèêîì. CHAN_HELP_SET_DESC - Ñèíòàêñèñ: SET #êàíàë DESC îïèñàíèå + Ñèíòàêñèñ: %s #êàíàë DESC îïèñàíèå Ïîçâîëÿåò óñòàíîâèòü îïèñàíèå êàíàëà, êîòîðîå áóäåò ïîêàçàíî ïðè èñïîëüçîâàíèè êîìàíä LIST è INFO. CHAN_HELP_SET_URL - Ñèíòàêñèñ: SET #êàíàë URL [àäðåñ] + Ñèíòàêñèñ: %s #êàíàë URL [àäðåñ] Ïîçâîëÿåò óñòàíîâèòü URL-àäðåñ êàíàëà. Äàííûé URL áóäåò ïîêàçàí òîãäà, êîãäà êòî-ëèáî çàïðîñèò èíôîðìàöèþ î êàíàëå ñ ïîìîùüþ @@ -4305,7 +4411,7 @@ CHAN_HELP_SET_URL äàííóþ êîìàíäó áåç ïàðàìåòðà. CHAN_HELP_SET_EMAIL - Ñèíòàêñèñ: SET #êàíàë EMAIL [àäðåñ@ïî÷òû] + Ñèíòàêñèñ: %s #êàíàë EMAIL [àäðåñ@ïî÷òû] Ïîçâîëÿåò óñòàíîâèòü àäðåñ ýëåêòðîííîé ïî÷òû êàíàëà. Ýòîò àäðåñ áóäåò ïîêàçàí òîãäà, êîãäà êòî-ëèáî çàïðîñèò èíôîðìàöèþ î êàíàëå @@ -4313,7 +4419,7 @@ CHAN_HELP_SET_EMAIL èñïîëüçóéòå äàííóþ êîìàíäó áåç ïàðàìåòðà. CHAN_HELP_SET_ENTRYMSG - Ñèíòàêñèñ: SET #êàíàë ENTRYMSG [òåêñò] + Ñèíòàêñèñ: %s #êàíàë ENTRYMSG [òåêñò] Ïîçâîëÿåò óñòàíîâèòü "ñîîáùåíèå ïðè âõîäå", êîòîðîå áóäåò îòïðàâëåíî íîòèñîì (notice) êàæäîìó âîøåäøåìó íà êàíàë ïîëüçîâàòåëþ. @@ -4321,7 +4427,7 @@ CHAN_HELP_SET_ENTRYMSG ñîîáùåíèå áóäåò óäàëåíî. CHAN_HELP_SET_BANTYPE - Ñèíòàêñèñ: SET #êàíàë BANTYPE òèï_áàíà + Ñèíòàêñèñ: %s #êàíàë BANTYPE òèï_áàíà Ïîçâîëÿåò óñòàíîâèòü øàáëîí áàíìàñêè, ïî êîòîðîé áóäåò çàáàíåí ïîëüçîâàòåëü êàíàëà, îòíîñèòåëüíî êîòîðîãî ïðèìåíÿåòñÿ ñåðâèñíàÿ @@ -4336,7 +4442,7 @@ CHAN_HELP_SET_BANTYPE 3 - áàí âèäà *!*èäåíò@*.äîìåí CHAN_HELP_SET_KEEPTOPIC - Ñèíòàêñèñ: SET #êàíàë KEEPTOPIC {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë KEEPTOPIC {ON | OFF} Ïîçâîëÿåò àêòèâèðîâàòü/äåàêòèâèðîâàòü îïöèþ õðàíåíèÿ òîïèêà íà êàíàëå. Ïðè âêëþ÷åííîì ðåæèìå õðàíåíèÿ òîïèêà, òåêñò òîïèêà êàíàëà @@ -4346,14 +4452,14 @@ CHAN_HELP_SET_KEEPTOPIC êòî-ëèáî çàéäåò). CHAN_HELP_SET_TOPICLOCK - Ñèíòàêñèñ: SET #êàíàë TOPICLOCK {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë TOPICLOCK {ON | OFF} Âêëþ÷àåò èëè âûêëþ÷àåò îïöèþ áëîêèðîâêè òîïèêà íà êàíàëå. Ïðè âêëþ÷åííîì ðåæèìå áëîêèðîâêè òîïèêà, %S ðàçðåøèò ìåíÿòü òîïèê êàíàëà òîëüêî ÷åðåç ñåðâèñíóþ êîìàíäó TOPIC. CHAN_HELP_SET_MLOCK - Ñèíòàêñèñ: SET #êàíàë MLOCK ðåæèìû + Ñèíòàêñèñ: %s #êàíàë MLOCK ðåæèìû MLOCK ïîçâîëÿåò âàì óñòàíîâèòü è çàáëîêèðîâàòü îïðåäåëåííûå ðåæèìû êàíàëà. Âû ìîæåòå çàáëîêèðîâàòü îò ñíÿòèÿ/óñòàíîâêè ëþáûå ðåæèìû, @@ -4389,7 +4495,7 @@ CHAN_HELP_SET_MLOCK ñâîáîäíî èçìåíåíû ëþáûì îïåðàòîðîì êàíàëà. CHAN_HELP_SET_PEACE - Ñèíòàêñèñ: SET #êàíàë PEACE {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë PEACE {ON | OFF} Àêòèâèðóåò/äåàêòèâèðóåò îïöèþ ñïîêîéñòâèÿ íà êàíàëå. Äàííûé ðåæèì ïîçâîëÿåò çàïðåòèòü èñïîëüçîâàíèå òàêèõ êîìàíä %S'à êàê BAN, @@ -4399,20 +4505,20 @@ CHAN_HELP_SET_PEACE ñìîæåò èñïîëüçîâàòü èõ îòíîñèòåëüíî ñåáÿ. CHAN_HELP_SET_PRIVATE - Ñèíòàêñèñ: SET #êàíàë PRIVATE {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë PRIVATE {ON | OFF} Àêòèâèðóåò/äåàêòèâèðóåò îïöèþ ïðèâàòíîñòè êàíàëà. Äàííûé ðåæèì ïîçâîëÿåò ñêðûòü âàø êàíàë â ñïèñêå êàíàëîâ ïî %R%S LIST. CHAN_HELP_SET_RESTRICTED - Ñèíòàêñèñ: SET #êàíàë RESTRICTED {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Ñèíòàêñèñ: SET #êàíàë SECURE {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë SECURE {ON | OFF} Àêòèâèðóåò/äåàêòèâèðóåò ðåæèì áåçîïàñíîñòè äëÿ êàíàëà. Êîãäà SECURE âêëþ÷åíî, òîëüêî ïîëüçîâàòåëè ñ çàðåãèñòðèðîâàííûìè @@ -4424,7 +4530,7 @@ CHAN_HELP_SET_SECURE âñåãî ëèøü ÷åðåç ñïèñîê ìàñîê íà %s. CHAN_HELP_SET_SECUREOPS - Ñèíòàêñèñ: SET #êàíàë SECUREOPS {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë SECUREOPS {ON | OFF} Àêòèâèðóåò/äåàêòèâèðóåò ðåæèì îãðàíè÷åíèÿ íà ïîëó÷åíèå ñòàòóñà îïåðàòîðà êàíàëà. Äàííûé ðåæèì ïîçâîëÿåò çàïðåòèòü âîçìîæíîñòü @@ -4433,7 +4539,7 @@ CHAN_HELP_SET_SECUREOPS ïîëó÷àåìîìó ñòàòóñó. CHAN_HELP_SET_SECUREFOUNDER - Ñèíòàêñèñ: SET #êàíàë SECUREFOUNDER {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë SECUREFOUNDER {ON | OFF} Àêòèâèðóåò/äåàêòèâèðóåò ðåæèì áåçîïàñíîñòè âëàäåëüöà íà êàíàëå. Àêòèâèðîâàíèå SECUREFOUNDER ïîçâîëÿåò âàì îãðàíè÷èòü âîçìîæíîñòü @@ -4442,7 +4548,7 @@ CHAN_HELP_SET_SECUREFOUNDER (è íå âàæíî, êòî òàì èäåíòèôèöèðîâàëñÿ ê êàíàëó ÷åðåç %S ID). CHAN_HELP_SET_SIGNKICK - Ñèíòàêñèñ: SET #êàíàë SIGNKICK {ON | LEVEL | OFF} + Ñèíòàêñèñ: %s #êàíàë SIGNKICK {ON | LEVEL | OFF} Âêëþ÷àåò èëè âûêëþ÷àåò îïöèþ "ïîäïèñàííûõ êèêîâ" íà êàíàëå. Àêòèâèðîâàíèå ðåæèìà SIGNKICK çàñòàâèò %S àâòîìàòè÷åñêè @@ -4455,7 +4561,7 @@ CHAN_HELP_SET_SIGNKICK áîëåå ïîäðîáíîé èíôîðìàöèè). CHAN_HELP_SET_XOP - Ñèíòàêñèñ: SET #êàíàë XOP {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë XOP {ON | OFF} Ïîçâîëÿåò àêòèâèðîâàòü/äåàêòèâèðîâàòü ñèñòåìó ïðèâåëåãèé xOP íà âàøåì êàíàëå. Îñîáåííîñòè äàííîé ñèñòåìû ñîñòîÿò â òîì, ÷òî âñå @@ -4482,7 +4588,7 @@ CHAN_HELP_SET_XOP êàêèõ-ëèáî ïðîáëåì. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4505,7 +4611,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Ñèíòàêñèñ: SET #êàíàë OPNOTICE {ON | OFF} + Ñèíòàêñèñ: %s #êàíàë OPNOTICE {ON | OFF} Âêëþ÷àåò èëè âûêëþ÷àåò îïöèþ OP-óâåäîìëåíèÿ íà âàøåì êàíàëå. Êîãäà îï-óâåäîìëåíèå âêëþ÷åíî, %S áóäåò ïîñûëàòü íîòèñ @@ -5087,13 +5193,6 @@ CHAN_SERVADMIN_HELP_DROP Êàê Àäìèíèñòðàòîð ñåðâèñîâ, âû ìîæåòå óäàëèòü ëþáîé çàðåãèñòðèðîâàííûé êàíàë ñåòè áåç êàêîé-ëèáî èäåíòèôèêàöèè ê íåìó. -CHAN_SERVADMIN_HELP_SET - - Àäìèíèñòðàòîðàì ñåðâèñîâ äîñòóïíà âîçìîæíîñòü èçìåíÿòü íàñòðîéêè - ëþáîãî çàðåãèñòðèðîâàííîãî êàíàëà ñåòè. Òàêæå, èì äîñòóïíà - óñòàíîâêà ñêðûòîé îïöèè NOEXPIRE (èñêëþ÷àåò êàíàë èç óñëîâèé - èñòå÷åíèÿ ðåãèñòðàöèè ïî âðåìåíè). - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Ñèíòàêñèñ: SET #êàíàë NOEXPIRE {ON | OFF} @@ -5423,8 +5522,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Îòêëþ÷èòü âñåõ ïîëüçîâàòåëåé ñ îïðåäåëåííîãî õîñòà OPER_HELP_CMD_AKILL AKILL Óïðàâëåíèå ñïèñêîì AKILL'îâ -OPER_HELP_CMD_SGLINE - SGLINE Óïðàâëåíèå ñïèñêîì SGLINE'îâ +OPER_HELP_CMD_SNLINE + SNLINE Óïðàâëåíèå ñïèñêîì SNLINE'îâ OPER_HELP_CMD_SQLINE SQLINE Óïðàâëåíèå ñïèñêîì SQLINE'îâ OPER_HELP_CMD_SZLINE @@ -5635,54 +5734,54 @@ OPER_HELP_AKILL AKILL CLEAR ïîçâîëÿåò ïîëíîñòüþ î÷èñòèòü ñïèñîê AKILL'îâ. -OPER_HELP_SGLINE - Ñèíòàêñèñ: SGLINE ADD [+ñðîê_èñòå÷åíèÿ] ìàñêà:ïðè÷èíà - SGLINE DEL {ìàñêà | íîìåð_çàïèñè | ñïèñîê_çàïèñåé} - SGLINE LIST [ìàñêà | ñïèñîê_çàïèñåé] - SGLINE VIEW [ìàñêà | ñïèñîê_çàïèñåé] - SGLINE CLEAR +OPER_HELP_SNLINE + Ñèíòàêñèñ: SNLINE ADD [+ñðîê_èñòå÷åíèÿ] ìàñêà:ïðè÷èíà + SNLINE DEL {ìàñêà | íîìåð_çàïèñè | ñïèñîê_çàïèñåé} + SNLINE LIST [ìàñêà | ñïèñîê_çàïèñåé] + SNLINE VIEW [ìàñêà | ñïèñîê_çàïèñåé] + SNLINE CLEAR - Ïîçâîëÿåò Îïåðàòîðàì ñåðâèñîâ óïðàâëÿòü ñïèñêîì ñåðâèñíûõ SGLINE'îâ. - SGLINE-çàïèñü ïîçâîëÿåò âàì ïîñòàâèòü ãëîáàëüíûé áàí íà îïðåäåëåííûé + Ïîçâîëÿåò Îïåðàòîðàì ñåðâèñîâ óïðàâëÿòü ñïèñêîì ñåðâèñíûõ SNLINE'îâ. + SNLINE-çàïèñü ïîçâîëÿåò âàì ïîñòàâèòü ãëîáàëüíûé áàí íà îïðåäåëåííûé RealName aka GECOS. Ëþáîé ïîëüçîâàòåëü, ðåàëüíîå èìÿ êîòîðîãî - ïîïàäåò ïîä ìàñêó êàêîé-ëèáî çàïèñè â SGLINE-ñïèñêå, áóäåò ñðàçó æå + ïîïàäåò ïîä ìàñêó êàêîé-ëèáî çàïèñè â SNLINE-ñïèñêå, áóäåò ñðàçó æå îòêëþ÷åí îò ñåòè è â äàëüíåéøåì, ñåðâèñû íå ïîçâîëÿò åìó ïîäêëþ÷èòñÿ. - Êîìàíäà SGLINE ADD äîáàâëÿåò ìàñêó ðåàëüíîãî èìåíè ñ óêàçàííîé - ïðè÷èíîé â ñïèñîê SGLINE'îâ (íàëè÷èå ïðè÷èíû - îáÿçàòåëüíî). + Êîìàíäà SNLINE ADD äîáàâëÿåò ìàñêó ðåàëüíîãî èìåíè ñ óêàçàííîé + ïðè÷èíîé â ñïèñîê SNLINE'îâ (íàëè÷èå ïðè÷èíû - îáÿçàòåëüíî). Çíà÷åíèå ñðîêà èñòå÷åíèÿ - ýòî öåëîå ÷èñëî, êîòîðîå ìîæåò áûòü îäíèì èç: d (äíåé), h (÷àñîâ), èëè m (ìèíóò). Òàêèå ñî÷åòàíèÿ êàê 1h30m - íåäîïóñòèìû. Åñëè åäèíèöà èçìåðåíèÿ íå óêàçàíà, òî ïî-óìîë÷àíèþ, îíà áóäåò ïðèíÿòà çà "d" - "äíè" (òàêèì îáðàçîì, - +30 áóäåò îçíà÷àòü 30 äíåé). ×òîáû äîáàâèòü ïîñòîÿííûé SGLINE, + +30 áóäåò îçíà÷àòü 30 äíåé). ×òîáû äîáàâèòü ïîñòîÿííûé SNLINE, èñïîëüçóéòå âðåìÿ èñòå÷åíèÿ ðàâíûì +0. Ïîìíèòå, ÷òî åñëè â êà÷åñòâå ïåðâîãî ñèìâîëà âòîðîãî ïàðàìåòðà óêàçàí çíàê "+" - âû äîëæíû îáîçíà÷èòü ñðîêè èñòå÷åíèÿ çàïèñè, äàæå åñëè ýòî áóäåò çíà÷åíèå ïî-óìî÷àíèþ. - Òåêóùåå âðåìÿ èñòå÷åíèÿ SGLINE'à ïî-óìîë÷àíèþ, ìîæíî óçíàòü ñ ïîìîùüþ + Òåêóùåå âðåìÿ èñòå÷åíèÿ SNLINE'à ïî-óìîë÷àíèþ, ìîæíî óçíàòü ñ ïîìîùüþ êîìàíäû STATS AKILL. Ïðèìå÷àíèå: òàê êàê ñòðîêè ðåàëüíûõ èìåí ìîãóò ñîäåðæàòü ïðîáåëû, ðàçäåëèòåëåì ìåæäó ìàñêîé ðåàëüíîãî èìåíè è ïðè÷èíîé áóäåò äâîåòî÷èå. - Êîìàíäà SGLINE DEL óäàëÿåò óêàçàííóþ ìàñêó èç ñïèñêà SGLINE'îâ. -  êà÷åñòâå ïàðàìåòðà âû ìîæåòå óêàçàòü íå òîëüêî ìàñêó SGLINE'à, íî + Êîìàíäà SNLINE DEL óäàëÿåò óêàçàííóþ ìàñêó èç ñïèñêà SNLINE'îâ. +  êà÷åñòâå ïàðàìåòðà âû ìîæåòå óêàçàòü íå òîëüêî ìàñêó SNLINE'à, íî è êîíêðåòíûé íîìåð çàïèñè èëè ñïèñîê çàïèñåé (ñì. ïðèìåðû èñïîëüçîâàíèÿ êîìàíäû LIST íèæå). - Êîìàíäà SGLINE LIST ïîêàçûâàåò òåêóùèé ñïèñîê SGLINE'îâ. + Êîìàíäà SNLINE LIST ïîêàçûâàåò òåêóùèé ñïèñîê SNLINE'îâ.  êà÷åñòâå äîïîëíèòåëüíîãî ïàðàìåòðà, âû ìîæåòå óêàçàòü ñèìâîëüíóþ ìàñêó, ÷òî ïîçâîëèò âàì ïîëó÷èòü ñïèñîê ñ êîíêðåòíûìè çàïèñÿìè, ïîïàäàþùèìè ïîä ýòó ìàñêó, èëè æå, âû ìîæåòå óêàçàòü ñïèñîê çàïèñåé. Íàïðèìåð: - SGLINE LIST 2-5,7-9 + SNLINE LIST 2-5,7-9 îòîáðàçèò âñå çàïèñè ñ 2-îé ïî 5-þ è ñ 7-îé ïî 9-þ. - SGLINE VIEW áîëåå ïîäðîáíàÿ âåðñèÿ SGLINE LIST, îíà ïîêàæåò êòî - äîáàâèë SGLINE, âðåìÿ óñòàíîâêè SGLINE'à, êîãäà îí èñòåêàåò, íó è, - êîíå÷íî æå, ìàñêó ðåàëüíîãî èìåíè è ïðè÷èíó SGLINE'à. + SNLINE VIEW áîëåå ïîäðîáíàÿ âåðñèÿ SNLINE LIST, îíà ïîêàæåò êòî + äîáàâèë SNLINE, âðåìÿ óñòàíîâêè SNLINE'à, êîãäà îí èñòåêàåò, íó è, + êîíå÷íî æå, ìàñêó ðåàëüíîãî èìåíè è ïðè÷èíó SNLINE'à. - SGLINE CLEAR ïîçâîëÿåò ïîëíîñòüþ î÷èñòèòü ñïèñîê SGLINE'îâ. + SNLINE CLEAR ïîçâîëÿåò ïîëíîñòüþ î÷èñòèòü ñïèñîê SNLINE'îâ. OPER_HELP_SQLINE Ñèíòàêñèñ: SQLINE ADD [+ñðîê_èñòå÷åíèÿ] ìàñêà ïðè÷èíà @@ -375,6 +375,14 @@ NICK_GROUP_TOO_MANY NICK_GROUP_JOINED %s grubuna dahil edildiniz. +# UNGROUP responses +NICK_UNGROUP_ONE_NICK + Your nick is not grouped to anything, you can't ungroup it. +NICK_UNGROUP_NOT_IN_GROUP + The nick %s is not in your group. +NICK_UNGROUP_SUCCESSFUL + Nick %s has been ungrouped from %s. + # IDENTIFY responses NICK_IDENTIFY_SYNTAX IDENTIFY þifreniz @@ -812,9 +820,9 @@ NICK_GLIST_HEADER_X NICK_GLIST_FOOTER Grupta %d nick var. NICK_GLIST_REPLY - %c%s -NICK_GLIST_REPLY_ADMIN - %c%s (expires in %s) + %s (expires in %s) +NICK_GLIST_REPLY_NOEXPIRE + %s (does not expire) # RECOVER responses NICK_RECOVER_SYNTAX @@ -864,18 +872,15 @@ NICK_SENDPASS_UNAVAILABLE SENDPASS komutu devre dýþý çünkü þifreleme(encryption) devrede. NICK_SENDPASS_SUBJECT Nick þifresi (%s) -NICK_SENDPASS_HEAD - Selam, -NICK_SENDPASS_LINE_1 - %s nickinizin þifresinin e-mail adresinize yollanmasýný istemiþsiniz. -NICK_SENDPASS_LINE_2 - Nickinizin Þifresi %s Güvenlik nedenlerinden dolayý, bu maili aldýktan sonra deðiþtirseniz iyi olur. -NICK_SENDPASS_LINE_3 - Eðer bu mailin neden size gönderildiðini bilmiyorsanýz, maili ciddiye almayýn. -NICK_SENDPASS_LINE_4 - LÜTFEN BU MAÝLE CEVAP VERMEYÝN! -NICK_SENDPASS_LINE_5 - %s yönetimi. +NICK_SENDPASS + Hi, + + You have requested to receive the password of nickname %s by e-mail. + The password is %s. For security purposes, you should change it as soon as you receive this mail. + + If you don't know why this mail was sent to you, please ignore it silently. + + %s administrators. NICK_SENDPASS_OK %s nickinin þifresi gönderildi. @@ -889,9 +894,8 @@ NICK_RESETPASS_MESSAGE You have requested to have the password for %s reset. To reset your password, type %R%s CONFIRM %s - If you don't know why this mail is sent to you, please ignore it silently. - PLEASE DON'T ANSWER TO THIS MAIL! + If you don't know why this mail was sent to you, please ignore it silently. %s administrators. NICK_RESETPASS_COMPLETE @@ -942,17 +946,14 @@ NICK_ENTER_REG_CODE A passcode has been sent to %s, please type %R%s confirm <passcode> to complete registration NICK_REG_MAIL_SUBJECT Nickname Registration (%s) -NICK_REG_MAIL_HEAD +NICK_REG_MAIL Hi, -NICK_REG_MAIL_LINE_1 - You have requested to register the following nickname %s. -NICK_REG_MAIL_LINE_2 + + You have requested to register the nickname %s on %s. Please type " %R%s confirm %s " to complete registration. -NICK_REG_MAIL_LINE_3 - If you don't know why this mail is sent to you, please ignore it silently. -NICK_REG_MAIL_LINE_4 - PLEASE DON'T ANSWER TO THIS MAIL! -NICK_REG_MAIL_LINE_5 + + If you don't know why this mail was sent to you, please ignore it silently. + %s administrators. NICK_GETPASS_PASSCODE_IS Passcode for %s is %s. @@ -1053,6 +1054,8 @@ CHAN_LEVEL_OWNER Allowed to use OWNER command CHAN_LEVEL_OWNERME Allowed to (de)owner him/herself +CHAN_LEVEL_FOUNDER + Allowed to issue commands restricted to channel founders # Automatic responses CHAN_IS_REGISTERED @@ -1102,6 +1105,34 @@ CHAN_DROP_DISABLED CHAN_DROPPED %s kanalýnýn kaydý silinmiþtir (dropped). +# SASET responses +CHAN_SASET_SYNTAX + SASET channel option parameters +CHAN_SASET_KEEPTOPIC_SYNTAX + SASET channel KEEPTOPIC {ON | OFF} +CHAN_SASET_OPNOTICE_SYNTAX + SASET channel OPNOTICE {ON | OFF} +CHAN_SASET_PEACE_SYNTAX + SASET channel PEACE {ON | OFF} +CHAN_SASET_PERSIST_SYNTAX + SASET channel PERSIST {ON | OFF} +CHAN_SASET_PRIVATE_SYNTAX + SASET channel PRIVATE {ON | OFF} +CHAN_SASET_RESTRICTED_SYNTAX + SASET channel RESTRICTED {ON | OFF} +CHAN_SASET_SECURE_SYNTAX + SASET channel SECURE {ON | OFF} +CHAN_SASET_SECUREFOUNDER_SYNTAX + SASET channel SECUREFOUNDER {ON | OFF} +CHAN_SASET_SECUREOPS_SYNTAX + SASET channel SECUREOPS {ON | OFF} +CHAN_SASET_SIGNKICK_SYNTAX + SASET channel SIGNKICK {ON | OFF} +CHAN_SASET_TOPICLOCK_SYNTAX + SASET channel TOPICLOCK {ON | OFF} +CHAN_SASET_XOP_SYNTAX + SASET channel XOP {ON | OFF} + # SET responses CHAN_SET_SYNTAX SET kanaladý özellik parametre @@ -2028,12 +2059,14 @@ MEMO_INFO_X_NOTIFY_SIGNON # Standard responses MEMO_MAIL_SUBJECT New memo -MEMO_MAIL_TEXT1 +NICK_MAIL_TEXT Hi %s -MEMO_MAIL_TEXT2 + You've just received a new memo from %s. This is memo number %d. -MEMO_MAIL_TEXT3 - Memo Text: + + Memo text: + + %s ########################################################################### # @@ -2566,22 +2599,22 @@ OPER_STATS_AKILL_EXPIRE_MIN Varsayýlan AKILL zaman aþýmý: 1 dakika OPER_STATS_AKILL_EXPIRE_NONE Varsayýlan AKILL zaman aþýmý: zaman aþýmý yok -OPER_STATS_SGLINE_COUNT - Þu anki SGLINE sayýsý: %d -OPER_STATS_SGLINE_EXPIRE_DAYS - Varsayýlan SGLINE zaman aþýmý süresi: %d gün -OPER_STATS_SGLINE_EXPIRE_DAY - Varsayýlan SGLINE zaman aþýmý süresi: 1 gün -OPER_STATS_SGLINE_EXPIRE_HOURS - Varsayýlan SGLINE zaman aþýmý süresi: %d saat -OPER_STATS_SGLINE_EXPIRE_HOUR - Varsayýlan SGLINE zaman aþýmý süresi: 1 saat -OPER_STATS_SGLINE_EXPIRE_MINS - Varsayýlan SGLINE zaman aþýmý süresi: %d dakika -OPER_STATS_SGLINE_EXPIRE_MIN - Varsayýlan SGLINE zaman aþýmý süresi: 1 dakika -OPER_STATS_SGLINE_EXPIRE_NONE - Varsayýlan SGLINE zaman aþýmý süresi: Zaman aþýmý yok +OPER_STATS_SNLINE_COUNT + Þu anki SNLINE sayýsý: %d +OPER_STATS_SNLINE_EXPIRE_DAYS + Varsayýlan SNLINE zaman aþýmý süresi: %d gün +OPER_STATS_SNLINE_EXPIRE_DAY + Varsayýlan SNLINE zaman aþýmý süresi: 1 gün +OPER_STATS_SNLINE_EXPIRE_HOURS + Varsayýlan SNLINE zaman aþýmý süresi: %d saat +OPER_STATS_SNLINE_EXPIRE_HOUR + Varsayýlan SNLINE zaman aþýmý süresi: 1 saat +OPER_STATS_SNLINE_EXPIRE_MINS + Varsayýlan SNLINE zaman aþýmý süresi: %d dakika +OPER_STATS_SNLINE_EXPIRE_MIN + Varsayýlan SNLINE zaman aþýmý süresi: 1 dakika +OPER_STATS_SNLINE_EXPIRE_NONE + Varsayýlan SNLINE zaman aþýmý süresi: Zaman aþýmý yok OPER_STATS_SQLINE_COUNT Su anki SQLINE sayisi: %d OPER_STATS_SQLINE_EXPIRE_DAYS @@ -2709,49 +2742,49 @@ OPER_AKILL_VIEW_FORMAT OPER_AKILL_CLEAR AKILL listesi temizlendi. -# SGLINE responses +# SNLINE responses OPER_CHANKILL_SYNTAX CHANKILL [+expiry] {#channel} [reason] -# SGLINE responses -OPER_SGLINE_SYNTAX - SGLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+zamanaþýmý] {mask | kayýt-sýrasý} [sebep]] -OPER_SGLINE_UNSUPPORTED - SGLINE bu networkte mevcut deðil. -OPER_SGLINE_EXISTS - %s zaten SGLINE listesinde. -OPER_SGLINE_ALREADY_COVERED +# SNLINE responses +OPER_SNLINE_SYNTAX + SNLINE {ADD | DEL | LIST | VIEW | CLEAR} [[+zamanaþýmý] {mask | kayýt-sýrasý} [sebep]] +OPER_SNLINE_UNSUPPORTED + SNLINE bu networkte mevcut deðil. +OPER_SNLINE_EXISTS + %s zaten SNLINE listesinde. +OPER_SNLINE_ALREADY_COVERED %s zaten %s tarafýndan deðiþtirildi. -OPER_SGLINE_REACHED_LIMIT - Sadece %d kiþi SGLINE listesinde olabilir. -OPER_SGLINE_ADDED - %s SGLINE listesinde eklendi. -OPER_SGLINE_CHANGED +OPER_SNLINE_REACHED_LIMIT + Sadece %d kiþi SNLINE listesinde olabilir. +OPER_SNLINE_ADDED + %s SNLINE listesinde eklendi. +OPER_SNLINE_CHANGED %s nickinin zaman aþýmý süresi deðiþtirildi. -OPER_SGLINE_NOT_FOUND - %s SGLINE listesinde bulunamadý. -OPER_SGLINE_NO_MATCH - SGLINE listesinde uyuþan kayýt bulunamadý. -OPER_SGLINE_DELETED - %s SGLINE listesinden silindi. -OPER_SGLINE_DELETED_ONE - SGLINE listesinden 1 kayýt silindi. -OPER_SGLINE_DELETED_SEVERAL - SGLINE listesinden %d kayýt silindi. -OPER_SGLINE_LIST_EMPTY - SGLINE listesi boþ. -OPER_SGLINE_LIST_HEADER - Þu anki SGLINE listesi: +OPER_SNLINE_NOT_FOUND + %s SNLINE listesinde bulunamadý. +OPER_SNLINE_NO_MATCH + SNLINE listesinde uyuþan kayýt bulunamadý. +OPER_SNLINE_DELETED + %s SNLINE listesinden silindi. +OPER_SNLINE_DELETED_ONE + SNLINE listesinden 1 kayýt silindi. +OPER_SNLINE_DELETED_SEVERAL + SNLINE listesinden %d kayýt silindi. +OPER_SNLINE_LIST_EMPTY + SNLINE listesi boþ. +OPER_SNLINE_LIST_HEADER + Þu anki SNLINE listesi: No Mask Sebep -OPER_SGLINE_LIST_FORMAT +OPER_SNLINE_LIST_FORMAT %3d %-32s %s -OPER_SGLINE_VIEW_HEADER - Þu anki SGLINE listesi: +OPER_SNLINE_VIEW_HEADER + Þu anki SNLINE listesi: # number, mask, set-by, set-time, expires, reason -OPER_SGLINE_VIEW_FORMAT +OPER_SNLINE_VIEW_FORMAT %3d %s (by %s on %s; %s) %s -OPER_SGLINE_CLEAR - SGLINE listesi temizlendi. +OPER_SNLINE_CLEAR + SNLINE listesi temizlendi. # SQLINE responses OPER_SQLINE_SYNTAX @@ -3404,6 +3437,8 @@ NICK_HELP_CMD_REGISTER REGISTER Nickinizi kaydeder NICK_HELP_CMD_GROUP GROUP Bir gruba dahil eder +NICK_HELP_CMD_UNGROUP + UNGROUP Remove a nick from a group NICK_HELP_CMD_IDENTIFY IDENTIFY Þifrenizle nickinizi tanýtýr NICK_HELP_CMD_ACCESS @@ -3536,6 +3571,15 @@ NICK_HELP_GROUP Not: bir gruptaki tüm nickler bir þifreye sahip olurlar. +NICK_HELP_UNGROUP + Syntax: UNGROUP [nick] + + This command ungroups your nick, or if given, the specificed nick, + from the group it is in. The ungrouped nick keeps its registration + time, password, email, greet, language, url, and icq. Everything + else is reset. You may not ungroup yourself if there is only one + nick in your group. + NICK_HELP_IDENTIFY Kullanýmý: IDENTIFY þifreniz @@ -3598,26 +3642,39 @@ NICK_HELP_ACCESS ACCESS LIST Mevcut access listesini görüntüler. -NICK_HELP_SET +NICK_HELP_SET_HEAD Kullanýmý: SET özellik parametre Çeþitli nick özelliklerini ayarlar. özellik þunlardan biri olabilir: +NICK_HELP_CMD_SET_DISPLAY DISPLAY Grubunuzun servislerde nasýl görüneceðini ayarlar +NICK_HELP_CMD_SET_PASSWORD PASSWORD Nickinize þifre belirtir +NICK_HELP_CMD_SET_LANGUAGE LANGUAGE Servislerin size hitap edeceði dili belirler +NICK_HELP_CMD_SET_URL URL Nickinizle bir URL yi iliþkilendirir +NICK_HELP_CMD_SET_EMAIL EMAIL Nickinizle bir email adresini iliþkilendirir +NICK_HELP_CMD_SET_ICQ ICQ Nickinizle bir ICQ numarasýný iliþikilendirir +NICK_HELP_CMD_SET_GREET GREET Nickiniz için bir karþýlama mesajý belirler +NICK_HELP_CMD_SET_KILL KILL Korumayý açar kapatýr +NICK_HELP_CMD_SET_SECURE SECURE Nick güvenliðini açar kapatýr +NICK_HELP_CMD_SET_PRIVATE PRIVATE Nickinizin %R%S LIST yazýldýðýnda görünmesini engeller +NICK_HELP_CMD_SET_HIDE HIDE Nickinizle ilgili bazý bilgileri saklar +NICK_HELP_CMD_SET_AUTOOP AUTOOP Should services op you automatically. +NICK_HELP_SET_TAIL Bu komutu kullanabilmek için önce, þifrenizle kendinizi tanýtmanýz gerekir (Daha fazla bilgi için @@ -3734,26 +3791,40 @@ NICK_HELP_SET_AUTOOP Sets whether you will be opped automatically. Set to ON to allow ChanServ to op you automatically when entering channels. -NICK_HELP_SASET +NICK_HELP_SASET_HEAD Syntax: SASET nickname option parameters. Sets various nickname options. option can be one of: +NICK_HELP_CMD_SASET_DISPLAY DISPLAY Set the display of the group in Services +NICK_HELP_CMD_SASET_PASSWORD PASSWORD Set the nickname password +NICK_HELP_CMD_SASET_URL URL Associate a URL with the nickname +NICK_HELP_CMD_SASET_EMAIL EMAIL Associate an E-mail address with the nickname +NICK_HELP_CMD_SASET_ICQ ICQ Associate an ICQ number with the nickname +NICK_HELP_CMD_SASET_GREET GREET Associate a greet message with the nickname +NICK_HELP_CMD_SASET_KILL KILL Turn protection on or off +NICK_HELP_CMD_SASET_SECURE SECURE Turn nickname security on or off +NICK_HELP_CMD_SASET_PRIVATE PRIVATE Prevent the nickname from appearing in a %R%S LIST +NICK_HELP_CMD_SASET_HIDE HIDE Hide certain pieces of nickname information +NICK_HELP_CMD_SASET_MSG MSG Change the communication method of Services +NICK_HELP_CMD_SASET_NOEXPIRE NOEXPIRE Prevent the nickname from expiring +NICK_HELP_CMD_SASET_LANGUAGE LANGUAGE Set the language Services will use when sending messages to nickname +NICK_HELP_SASET_TAIL Type %R%S HELP SASET option for more information on a specific option. The options will be set on the given @@ -4072,8 +4143,8 @@ NICK_SERVADMIN_HELP_DROP NICK_SERVADMIN_HELP_INFO - Servis adminleri ALL parametresini herhangi bir nick için - kullanabilirler. + Services Operators with the nickserv/auspex privilege may + use the ALL parameter with any nick. NICK_SERVADMIN_HELP_LIST Kullanýmý: LIST model [FORBIDDEN] [SUSPENDED] [NOEXPIRE] [UNCONFIRMED] @@ -4190,6 +4261,8 @@ CHAN_HELP_CMD_REGISTER REGISTER Kanalý kaydeder CHAN_HELP_CMD_SET SET Kanal özelliklerini ve bilgisini ayarlar +CHAN_HELP_CMD_SASET + SASET Forcefully set channel options and information CHAN_HELP_CMD_QOP QOP Modify the list of QOP users CHAN_HELP_CMD_AOP @@ -4290,7 +4363,15 @@ CHAN_HELP_DROP Kanalýn kaydýný siler. -CHAN_HELP_SET +CHAN_HELP_SASET_HEAD + Syntax: SASET channel option parameters + + Allows Services Operators to forcefully change settings + on channels. + + Available options: + +CHAN_HELP_SET_HEAD Kullanýmý: SET kanaladý özellik parametre Kanal founderýnýn çeþitli kanal özelliklerini ve diðer bilgileri @@ -4298,40 +4379,63 @@ CHAN_HELP_SET Mevcut özellikler: +CHAN_HELP_CMD_SET_FOUNDER FOUNDER Kanal founderýný belirler +CHAN_HELP_CMD_SET_SUCCESSOR SUCCESSOR Kanal successorýný belirler +CHAN_HELP_CMD_SET_DESC DESC Kanal açýklamasýný belirler +CHAN_HELP_CMD_SET_URL URL Kanala bir URL adresini iliþkilendirir +CHAN_HELP_CMD_SET_EMAIL EMAIL Kanala bir E-mail adresini iliþkilendirir +CHAN_HELP_CMD_SET_ENTRYMSG ENTRYMSG Kanala giren kullanýcýlara gönderilecek mesajý belirler +CHAN_HELP_CMD_SET_BANTYPE BANTYPE Servislerin kanalda ne tip ban koyacaðýný belirler +CHAN_HELP_CMD_SET_KEEPTOPIC KEEPTOPIC Kanalda kimse olmasa bile topiði hatýrlar +CHAN_HELP_CMD_SET_TOPICLOCK TOPICLOCK Topic sadece SET TOPIC komutuyla deðiþtirilir +CHAN_HELP_CMD_SET_MLOCK MLOCK Kanal modlarýný kitler yada açar +CHAN_HELP_CMD_SET_PRIVATE PRIVATE LIST komutuyla kanal listelenmez +CHAN_HELP_CMD_SET_RESTRICTED RESTRICTED Kanala izinli giriþ gerektirir +CHAN_HELP_CMD_SET_SECURE SECURE %S güvenlik özelliklerini aktifleþtirir +CHAN_HELP_CMD_SET_SECUREOPS SECUREOPS Kanal opu durumunun sýký kontrolünü saðlar +CHAN_HELP_CMD_SET_SECUREFOUNDER SECUREFOUNDER Kanal founderý durumunun sýký kontrolünü saðlar +CHAN_HELP_CMD_SET_SIGNKICK SIGNKICK KICK komutuyla yapýlan atmalarý iþaretler +CHAN_HELP_CMD_SET_OPNOTICE OPNOTICE OP/DEOP komutlarý kullanýldýðýnda mesaj yollar +CHAN_HELP_CMD_SET_PEACE PEACE kritik komutlarin kullanilmasini engeller +CHAN_HELP_CMD_SET_XOP XOP Ayricalik sistemleri arasinda geçisi saglar +CHAN_HELP_CMD_SET_PERSIST PERSIST Set the channel as permanent - +CHAN_HELP_CMD_SET_NOEXPIRE + NOEXPIRE Prevent the channel from expiring +CHAN_HELP_SET_TAIL + Belirli bir özellik hakkýnda daha fazla bilgi için %R%S HELP özellik yazýn. CHAN_HELP_SET_FOUNDER - Kullanýmý: SET kanaladý FOUNDER nick + Kullanýmý: %s kanaladý FOUNDER nick Kanal founderýný deðiþtirir. Yeni nickin kayýtlý olmasý gereklidir. CHAN_HELP_SET_SUCCESSOR - Kullanýmý: SET kanaladý SUCCESSOR nick + Kullanýmý: %s kanaladý SUCCESSOR nick Kanal successorýný belirler, deðiþtirir. Eðer bir kanalýn founderýnýn nicki zaman aþýmýna uðrayýp kaydý silinirse @@ -4342,13 +4446,13 @@ CHAN_HELP_SET_SUCCESSOR Komutta belirtilen nickin kayýtlý olmasý gereklidir. CHAN_HELP_SET_DESC - Kullanýmý: SET kanaladý DESC açýklama + Kullanýmý: %s kanaladý DESC açýklama LIST ve INFO komutlarý kullanýldýðýnda gözükecek kanal açýklamasýný belirler. CHAN_HELP_SET_URL - Kullanýmý: SET kanaladý URL [urladresi] + Kullanýmý: %s kanaladý URL [urladresi] Belirtilen URL adresini kanal ile iliþkilendirir. Bu URL adresi birisi kanal hakkýnda bilgi almak için INFO @@ -4357,7 +4461,7 @@ CHAN_HELP_SET_URL silinir. CHAN_HELP_SET_EMAIL - Kullanýmý: SET kanaladý EMAIL [emailadresi] + Kullanýmý: %s kanaladý EMAIL [emailadresi] Belirtilen E-mail adresini kanal ile iliþkilendirir.Bu E-mail adresi birisi kanal hakkýnda bilgi almak için INFO komutunu @@ -4366,14 +4470,14 @@ CHAN_HELP_SET_EMAIL silinir. CHAN_HELP_SET_ENTRYMSG - Kullanýmý: SET kanaladý ENTRYMSG [mesaj] + Kullanýmý: %s kanaladý ENTRYMSG [mesaj] Kanala giren kullanýcýlara notice þeklinde gönderilecek mesajý belirler. Eðer mesaj parametresi belirtilmezse giren kullanýcýya bir mesaj gönderilmez. CHAN_HELP_SET_BANTYPE - Kullanýmý: SET kanaladý BANTYPE bantipi + Kullanýmý: %s kanaladý BANTYPE bantipi Servislerin birini kanaldan banlarken kullanacaðý ban tipini belirler. @@ -4386,7 +4490,7 @@ CHAN_HELP_SET_BANTYPE 3: *!*user@*.domain formatýnda ban için CHAN_HELP_SET_KEEPTOPIC - Kullanýmý: SET kanaladý KEEPTOPIC {ON | OFF} + Kullanýmý: %s kanaladý KEEPTOPIC {ON | OFF} Bir kanal için topic hatýrlamayý aktifleþtirir yada kapatýr. topic hatýrlama aktifse kanal kapansa bile kanal topic i @@ -4394,14 +4498,14 @@ CHAN_HELP_SET_KEEPTOPIC topic geçerli olur. CHAN_HELP_SET_TOPICLOCK - Kullanýmý: SET kanaladý TOPICLOCK {ON | OFF} + Kullanýmý: %s kanaladý TOPICLOCK {ON | OFF} Bir kanal için topic kilidini aktifleþtirir yada kapatýr. topic kilidi aktifse, %S SET TOPIC komutunun dýþýnda kanal topic inin deðiþtirilmesine izin vermez. CHAN_HELP_SET_MLOCK - Kullanýmý: SET kanaladý MLOCK modlar + Kullanýmý: %s kanaladý MLOCK modlar Bir kanal için mod-kilidini aktifleþtirir. %S belirlediðiniz modlarýn her zaman açýk yada kapalý olacaðýný ayarlar. @@ -4431,7 +4535,7 @@ CHAN_HELP_SET_MLOCK kapanacak þekilde serbest býrakýr. CHAN_HELP_SET_PEACE - Kullanimi: SET kanaladi PEACE {ON | OFF} + Kullanimi: %s kanaladi PEACE {ON | OFF} Bir kanalin peace özelligini açar veya kapatir. peace özelligi ayarlandiginda, hic kimse seviyesi kendinden @@ -4439,20 +4543,20 @@ CHAN_HELP_SET_PEACE seviyesini degistiremez. CHAN_HELP_SET_PRIVATE - Kullanýmý: SET kanaladý PRIVATE {ON | OFF} + Kullanýmý: %s kanaladý PRIVATE {ON | OFF} Bir kanal için private özelliðini açar kapatýr. private özelliði aktifse, %R%S LIST komutuyla kanal listelenemez. CHAN_HELP_SET_RESTRICTED - Kullanýmý: SET kanaladý RESTRICTED {ON | OFF} + Kullanýmý: %s kanaladý RESTRICTED {ON | OFF} Enables or disables the restricted access option for a channel. When restricted access is set, users not on the access list will instead be kicked and banned from the channel. CHAN_HELP_SET_SECURE - Kullanýmý: SET kanaladý SECURE {ON | OFF} + Kullanýmý: %s kanaladý SECURE {ON | OFF} Bir kanal için %S'ün güvenlik özelliklerini açar veya kapatýr. SECURE özelliði aktifse, sadece nicki kayýtlý @@ -4461,14 +4565,14 @@ CHAN_HELP_SET_SECURE alabilirler.(mesela op olabilirler) CHAN_HELP_SET_SECUREOPS - Kullanýmý: SET kanaladý SECUREOPS {ON | OFF} + Kullanýmý: %s kanaladý SECUREOPS {ON | OFF} Bir kanal için güvenli op özelliðini açar veya kapatýr. güvenli op özelliði aktifse, access listesinde olmayan kullanýcýlar kanalda op olamazlar. CHAN_HELP_SET_SECUREFOUNDER - Kullanýmý: SET kanaladý SECUREFOUNDER {ON | OFF} + Kullanýmý: %s kanaladý SECUREFOUNDER {ON | OFF} Bir kanal için güvenli founder özelliðini açar yada kapatýr. güvenli founder özelliði aktifse, sadece gerçek founder @@ -4478,7 +4582,7 @@ CHAN_HELP_SET_SECUREFOUNDER ama nicki founderýn nicki olmayanlar bu komutlarý kullanamazlar. CHAN_HELP_SET_SIGNKICK - Kullanýmý: SET kanaladý SIGNKICK {ON | LEVEL | OFF} + Kullanýmý: %s kanaladý SIGNKICK {ON | LEVEL | OFF} Bir kanal için iþaretli atmayý açar yada kapatýr. SIGNKICK ayarlandýðý zaman, %S KICK @@ -4491,7 +4595,7 @@ CHAN_HELP_SET_SIGNKICK bilgi için %R%S HELP LEVELS yazýn. CHAN_HELP_SET_XOP - Kullanimi: SET kanaladi XOP {ON | OFF} + Kullanimi: %s kanaladi XOP {ON | OFF} Bir kanalin xOP sistemini açar veya kapatir. XOP ayarlandigi zaman, AOP/SOP/VOP komutlariyla @@ -4514,7 +4618,7 @@ CHAN_HELP_SET_XOP bir problem çikarmaz. CHAN_HELP_SET_PERSIST - Syntax: SET channel PERSIST {ON | OFF} + Syntax: %s channel PERSIST {ON | OFF} Enables or disables the persistant channel setting. When persistant is set, the service bot will remain @@ -4537,7 +4641,7 @@ CHAN_HELP_SET_PERSIST set persist on or off. CHAN_HELP_SET_OPNOTICE - Kullanýmý: SET kanaladý OPNOTICE {ON | OFF} + Kullanýmý: %s kanaladý OPNOTICE {ON | OFF} Bir kanal için op-notu özelliðini açar yada kapatýr. op-notu özelliði aktifse, %S kanala bir kullanýcý @@ -5057,13 +5161,6 @@ CHAN_SERVADMIN_HELP_DROP Belirtilen kanalýn kaydýný siler. Sadece Servis adminleri kanalý tanýtmadan kaydýný silebilirler. -CHAN_SERVADMIN_HELP_SET - - Servis adminleri NOEXPIRE özelliðini ayarlayarak istedikleri - kanalýn zaman aþýmýna uðramasýný engelleyebilirler. - Ek olarak, Servis adminleri þifreyle kanalý tanýtmaya gerek - olmadan bir kanalýn tüm özelliklerini ayarlayabilirler. - CHAN_SERVADMIN_HELP_SET_NOEXPIRE Kullanýmý: SET kanaladý NOEXPIRE {ON | OFF} @@ -5398,8 +5495,8 @@ OPER_HELP_CMD_KILLCLONES KILLCLONES Ayni ip'deki tum kullanicilari kill'ler. OPER_HELP_CMD_AKILL AKILL AKILL listesini düzenler -OPER_HELP_CMD_SGLINE - SGLINE SGLINE listesini düzenler +OPER_HELP_CMD_SNLINE + SNLINE SNLINE listesini düzenler OPER_HELP_CMD_SQLINE SQLINE SQLINE listesini düzenler OPER_HELP_CMD_SZLINE @@ -5601,50 +5698,50 @@ OPER_HELP_AKILL Servis operatörlerinin Kullanýmýyla sýnýrlýdýr. -OPER_HELP_SGLINE - Kullanýmý: SGLINE ADD [+zamanaþýmý] mask:sebep - SGLINE DEL {mask | kayýt-no | liste} - SGLINE LIST [mask | liste] - SGLINE VIEW [mask | liste] - SGLINE CLEAR +OPER_HELP_SNLINE + Kullanýmý: SNLINE ADD [+zamanaþýmý] mask:sebep + SNLINE DEL {mask | kayýt-no | liste} + SNLINE LIST [mask | liste] + SNLINE VIEW [mask | liste] + SNLINE CLEAR - Servis operatörlerinin SGLINE listesi oluþturmalarýný saðlar. - Eðer SGLINE listesindeki bir kullanýcý gerçek ismi(realname) + Servis operatörlerinin SNLINE listesi oluþturmalarýný saðlar. + Eðer SNLINE listesindeki bir kullanýcý gerçek ismi(realname) servera baðlanmaya çalýþan bir kullanýcýnýnkiyle uyuþuyorsa o kullanýcýnýn servera baðlanmasý engellenir. - SGLINE ADD komutu belirtilen realname(gerçek isim) mask ýný - SGLINE listesine bir sebeple(belirtilmesi zorunludur) + SNLINE ADD komutu belirtilen realname(gerçek isim) mask ýný + SNLINE listesine bir sebeple(belirtilmesi zorunludur) birlikte ekler. zamanaþýmý zaman belirleyici olarak tanýmlanýr ve þunlar birini takip etmelidir: d (gün), h (saat), veya m (dakika). 1h30m þeklindeki kombinasyonlar kullanýlamaz. Eðer zaman tanýmlayýcý öðe konulmazsa varsayýlan olarak gün kabul edilir (yani +30 un manasý - 30 gündür). Zaman aþýmýna uðramayacak bir SGLINE eklemek için +0 + 30 gündür). Zaman aþýmýna uðramayacak bir SNLINE eklemek için +0 kullanýn. Eklenecek realname mask ý + ile baþlýyorsa, o zaman zaman aþýmý süresi varsayýlanla ayný olsa bile belirtilmelidir. - Mevcut SGLINE varsayýlan zaman aþýmý süresi STATS AKILL komutuyla + Mevcut SNLINE varsayýlan zaman aþýmý süresi STATS AKILL komutuyla bulunabilir. Not: realname maský boþluk içerebileceðinden bunla sebep arasýnda iki nokta üstüste(:) kullanýlmalýdýr. - SGLINE DEL komutu belirtilen maský(eðer listede mevcutsa) SGLINE + SNLINE DEL komutu belirtilen maský(eðer listede mevcutsa) SNLINE listesinden siler. eðer bir kayýt numaralarý listesi belirtilmiþse o kayýtlar silinir. (Aþaðýdaki LIST için verilmiþ örneði inceleyin.) - SGLINE LIST komutu SGLINE listesini görüntüler. Eðer bir yýldýzlý + SNLINE LIST komutu SNLINE listesini görüntüler. Eðer bir yýldýzlý mask verilmiþse, sadece o maskla uyuþan kayýtlarý içeren bir liste görüntülenir. Eðer bir kayýt numaralarý listesi belirtilmiþse, sadece o kayýtlar görüntülenir; örneðin: - SGLINE LIST 2-5,7-9 - 2 den 5 e 7 den 9 a kadar olan SGLINE kayýtlarýný listeler. + SNLINE LIST 2-5,7-9 + 2 den 5 e 7 den 9 a kadar olan SNLINE kayýtlarýný listeler. - SGLINE VIEW komutu SGLINE LIST komutunun daha açýklayýcý bilgi - veren þeklidir, ve SGLINE ý kimin eklediðini, eklendiði tarihi, ve + SNLINE VIEW komutu SNLINE LIST komutunun daha açýklayýcý bilgi + veren þeklidir, ve SNLINE ý kimin eklediðini, eklendiði tarihi, ve ne zaman sona ereceðini realname ve sebeple birlikte gösterir. - SGLINE CLEAR komutu SGLINE listesindeki tüm kayýtlarý siler. + SNLINE CLEAR komutu SNLINE listesindeki tüm kayýtlarý siler. Servis operatörlerinin Kullanýmýyla sýnýrlýdýr. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4bad367b4..b9c082c7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,15 +1,24 @@ -# Find all the *.c and *.cpp files within the current source directory, and sort the list -file(GLOB SRC_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") +# Find all the *.cpp files within the current source directory, and sort the list file(GLOB SRC_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") set(SRC_SRCS ${SRC_SRCS_C} ${SRC_SRCS_CPP}) + # Don't include win32_memory.cpp, it's only required by Visual Studio to override it's override of the new/delete operators remove_item_from_list(SRC_SRCS win32_memory.cpp) + # If not using Windows, don't include windows.cpp, as it's Windows-specific if(NOT WIN32) remove_item_from_list(SRC_SRCS windows.cpp) endif(NOT WIN32) sort_list(SRC_SRCS) +# If using Windows, remove the pthread threading engine from the list +if(WIN32) + remove_item_from_list(SRC_SRCS threadengine_pthread.cpp) +# If not using Windows, remove the Windows threading engine from the list +else(WIN32) + remove_item_from_list(SRC_SRCS threadengine_win32.cpp) +endif(WIN32) + # Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though) set_source_files_properties(${SRC_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}") diff --git a/src/Makefile b/src/Makefile index 949e7e8ec..d4ce6625e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,14 +1,15 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \ - config.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ - memory.o memoserv.o messages.o misc.o modules.o nickserv.o operserv.o \ - process.o protocol.o send.o servers.o sessions.o slist.o sockets.o opertype.o users.o module.o modulemanager.o configreader.o \ - wildcard.o nickcore.o nickalias.o timers.o modes.o regchannel.o - -INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \ - ../include/pseudo.h ../include/sysconf.h ../include/config.h \ - ../include/messages.h ../include/services.h \ + config.o configreader.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ + memory.o memoserv.o messages.o misc.o modes.o modules.o module.o modulemanager.o nickalias.o \ + nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o \ + sockets.o threadengine.o threadengine_pthread.o timers.o opertype.o users.o wildcard.o + +INCLUDES = ../include/commands.h ../include/language.h \ + ../include/sysconf.h ../include/config.h \ + ../include/services.h ../include/regchannel.h \ ../include/timers.h ../include/extern.h \ - ../include/modules.h ../include/slist.h ../include/hashcomp.h + ../include/modules.h ../include/operserv.h ../include/hashcomp.h \ + ../include/threadengine.h ../include/mail.h MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'LDFLAGS=${LDFLAGS}' 'INSTDIR=${INSTDIR}' 'INSTALL=${INSTALL}' \ @@ -18,9 +19,6 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}' \ 'MAKEBIN=${MAKEBIN}' 'MYSQLDIR=${MYSQLDIR}' -.c.o: - $(MAKEBIN) $(CC) $(CFLAGS) -I../include/ -c $< - .cpp.o: $(MAKEBIN) $(CC) $(CFLAGS) -I../include/ -c $< @@ -33,48 +31,50 @@ services: $(OBJS) $(MAKEBIN) $(CC) $(CFLAGS) $(OBJS) $(ANOPELIBS) $(MLIBS) -o $@ $(LDFLAGS) $(OBJS): Makefile -modes.o: modes.cpp $(INCLUDES) -timers.o: timers.cpp $(INCLUDES) -nickcore.o: nickcore.cpp $(INCLUDES) -nickalias.o: nickalias.cpp $(INCLUDES) -actions.o: actions.c $(INCLUDES) -base64.o: base64.c $(INCLUDES) +actions.o: actions.cpp $(INCLUDES) +base64.o: base64.cpp $(INCLUDES) bots.o: bots.cpp $(INCLUDES) -botserv.o: botserv.c $(INCLUDES) -channels.o: channels.c $(INCLUDES) -chanserv.o: chanserv.c $(INCLUDES) -command.o: command.cpp $(INCLUDES) -commands.o: commands.c $(INCLUDES) -compat.o: compat.c $(INCLUDES) -config.o: config.c $(INCLUDES) -encrypt.o: encrypt.c $(INCLUDES) -init.o: init.c $(INCLUDES) -ircd.o: ircd.c $(INCLUDES) -hostserv.o: hostserv.c $(INCLUDES) -language.o: language.c $(INCLUDES) -log.o: log.c $(INCLUDES) -mail.o: mail.c $(INCLUDES) -main.o: main.c $(INCLUDES) -memory.o: memory.c $(INCLUDES) -memoserv.o: memoserv.c $(INCLUDES) -messages.o: messages.c $(INCLUDES) -modules.o: modules.c $(INCLUDES) +botserv.o: botserv.cpp $(INCLUDES) +channels.o: channels.cpp $(INCLUDES) +chanserv.o: chanserv.cpp $(INCLUDES) +command.o: command.cpp $(INCLUDES) +commands.o: commands.cpp $(INCLUDES) +compat.o: compat.cpp $(INCLUDES) +config.o: config.cpp $(INCLUDES) +configreader.o: configreader.cpp $(INCLUDES) +encrypt.o: encrypt.cpp $(INCLUDES) +init.o: init.cpp $(INCLUDES) +ircd.o: ircd.cpp $(INCLUDES) +hostserv.o: hostserv.cpp $(INCLUDES) +language.o: language.cpp $(INCLUDES) +log.o: log.cpp $(INCLUDES) +mail.o: mail.cpp $(INCLUDES) +main.o: main.cpp $(INCLUDES) +memory.o: memory.cpp $(INCLUDES) +memoserv.o: memoserv.cpp $(INCLUDES) +messages.o: messages.cpp $(INCLUDES) +modes.o: modes.cpp $(INCLUDES) +modules.o: modules.cpp $(INCLUDES) module.o: module.cpp $(INCLUDES) modulemanager.o: modulemanager.cpp $(INCLUDES) -misc.o: misc.c $(INCLUDES) -nickserv.o: nickserv.c $(INCLUDES) -operserv.o: operserv.c $(INCLUDES) -process.o: process.c $(INCLUDES) +misc.o: misc.cpp $(INCLUDES) +nickalias.o: nickalias.cpp $(INCLUDES) +nickcore.o: nickcore.cpp $(INCLUDES) +nickserv.o: nickserv.cpp $(INCLUDES) +operserv.o: operserv.cpp $(INCLUDES) +opertype.o: opertype.cpp $(INCLUDES) +process.o: process.cpp $(INCLUDES) protocol.o: protocol.cpp $(INCLUDES) regchannel.o: regchannel.cpp $(INCLUDES) -send.o: send.c $(INCLUDES) -servers.o: servers.c $(INCLUDES) -sessions.o: sessions.c $(INCLUDES) -slist.o: slist.c $(INCLUDES) +send.o: send.cpp $(INCLUDES) +servers.o: servers.cpp $(INCLUDES) +sessions.o: sessions.cpp $(INCLUDES) +slist.o: slist.cpp $(INCLUDES) sockets.o: sockets.cpp $(INCLUDES) -opertype.o: opertype.cpp $(INCLUDES) -users.o: users.c $(INCLUDES) -vsnprintf.o: vsnprintf.c $(INCLUDES) +threadengine.o: threadengine.cpp $(INCLUDES) +threadengine_pthread.o: threadengine_pthread.cpp $(INCLUDES) +timers.o: timers.cpp $(INCLUDES) +users.o: users.cpp $(INCLUDES) wildcard.o: wildcard.cpp $(INCLUDES) modules: DUMMY diff --git a/src/actions.c b/src/actions.cpp index 471e1273f..00ed01100 100644 --- a/src/actions.c +++ b/src/actions.cpp @@ -70,52 +70,6 @@ void kill_user(const std::string &source, const std::string &user, const std::st /*************************************************************************/ /** - * Check and enforce SQlines - * @param mask of the sqline - * @param reason for the sqline - * @return void - */ -void sqline(const std::string &mask, const std::string &reason) -{ - int i; - Channel *c, *next; - - if (ircd->chansqline) - { - if (mask[0] == '#') - { - ircdproto->SendSQLine(mask, reason); - - for (i = 0; i < 1024; ++i) - { - for (c = chanlist[i]; c; c = next) - { - next = c->next; - - if (!Anope::Match(c->name, mask, false)) - continue; - for (CUserList::iterator it = c->users.begin(); it != c->users.end();) - { - UserContainer *uc = *it; - ++it; - - if (is_oper(uc->user)) - continue; - c->Kick(NULL, uc->user, "%s", reason.c_str()); - } - } - } - } - else - ircdproto->SendSQLine(mask, reason); - } - else - ircdproto->SendSQLine(mask, reason); -} - -/*************************************************************************/ - -/** * Unban the nick from a channel * @param ci channel info for the channel * @param nick to remove the ban for diff --git a/src/base64.c b/src/base64.cpp index 3f576e96a..3f576e96a 100644 --- a/src/base64.c +++ b/src/base64.cpp diff --git a/src/bots.cpp b/src/bots.cpp index 37cd553d1..e9021b188 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -10,6 +10,18 @@ #include "services.h" #include "modules.h" +#include "commands.h" + +botinfo_map BotListByNick; +botinfo_uid_map BotListByUID; + +BotInfo *BotServ = NULL; +BotInfo *ChanServ = NULL; +BotInfo *Global = NULL; +BotInfo *HostServ = NULL; +BotInfo *MemoServ = NULL; +BotInfo *NickServ = NULL; +BotInfo *OperServ = NULL; BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std::string &nhost, const std::string &nreal) { @@ -19,100 +31,87 @@ BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std:: this->real = nreal; this->lastmsg = this->created = time(NULL); this->uid = ts6_uid_retrieve(); - this->cmdTable = NULL; - ++nbots; this->chancount = 0; ci::string ci_nick(nnick.c_str()); if (Config.s_ChanServ && ci_nick == Config.s_ChanServ) { - this->cmdTable = CHANSERV; - this->SetFlag(BI_CHANSERV); + ChanServ = this; } else if (Config.s_BotServ && ci_nick == Config.s_BotServ) { - this->cmdTable = BOTSERV; - this->SetFlag(BI_BOTSERV); + BotServ = this; } else if (Config.s_HostServ && ci_nick == Config.s_HostServ) { - this->cmdTable = HOSTSERV; - this->SetFlag(BI_HOSTSERV); + HostServ = this; } else if (Config.s_OperServ && ci_nick == Config.s_OperServ) { - this->cmdTable = OPERSERV; - this->SetFlag(BI_OPERSERV); + OperServ = this; } else if (Config.s_MemoServ && ci_nick == Config.s_MemoServ) { - this->cmdTable = MEMOSERV; - this->SetFlag(BI_MEMOSERV); + MemoServ = this; } else if (Config.s_NickServ && ci_nick == Config.s_NickServ) { - this->cmdTable = NICKSERV; - this->SetFlag(BI_NICKSERV); + NickServ = this; } else if (Config.s_GlobalNoticer && ci_nick == Config.s_GlobalNoticer) { - this->SetFlag(BI_GLOBAL); + Global = this; } - insert_bot(this); // XXX, this is ugly, but it needs to stay until hashing of bots is redone in STL. + BotListByNick[this->nick.c_str()] = this; + if (!this->uid.empty()) + BotListByUID[this->uid] = this; // If we're synchronised with the uplink already, call introduce_user() for this bot. - if (serv_uplink && serv_uplink->sync == SSYNC_DONE) + if (Me && Me->GetUplink()->IsSynced()) { ircdproto->SendClientIntroduction(this->nick, this->user, this->host, this->real, ircd->pseudoclient_mode, this->uid); - ircdproto->SendSQLine(this->nick, "Reserved for services"); + XLine x(this->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); } } BotInfo::~BotInfo() { - int i; - ChannelInfo *ci; - - for (i = 0; i < 256; ++i) - for (ci = chanlists[i]; ci; ci = ci->next) - if (ci->bi == this) - ci->bi = NULL; - - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - botlists[tolower(this->nick[0])] = this->next; - - --nbots; + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; + + if (ci->bi == this) + { + ci->bi = NULL; + } + } + + BotListByNick.erase(this->nick.c_str()); + if (!this->uid.empty()) + BotListByUID.erase(this->uid); } void BotInfo::ChangeNick(const char *newnick) { - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - botlists[tolower(this->nick[0])] = this->next; + BotListByNick.erase(this->nick.c_str()); this->nick = newnick; - insert_bot(this); + BotListByNick[this->nick.c_str()] = this; } void BotInfo::RejoinAll() { - int i; - ChannelInfo *ci; + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; - for (i = 0; i < 256; ++i) - for (ci = chanlists[i]; ci; ci = ci->next) - if (ci->bi == this && ci->c && (ci->c->users.size() >= Config.BSMinUsers)) - bot_join(ci); + if (ci->bi == this && ci->c && ci->c->users.size() >= Config.BSMinUsers) + bot_join(ci); + } } void BotInfo::Assign(User *u, ChannelInfo *ci) diff --git a/src/botserv.c b/src/botserv.cpp index 54b968dec..2dd96706d 100644 --- a/src/botserv.c +++ b/src/botserv.cpp @@ -14,14 +14,8 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" - -/*************************************************************************/ - -BotInfo *botlists[256]; /* Hash list of bots */ -int nbots = 0; - -/*************************************************************************/ +#include "modules.h" +#include "language.h" static UserData *get_user_data(Channel * c, User * u); @@ -44,18 +38,17 @@ void moduleAddBotServCmds() { void get_botserv_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - int i; - BotInfo *bi; - - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - count++; - mem += sizeof(*bi); - mem += bi->nick.size() + 1; - mem += bi->user.size() + 1; - mem += bi->host.size() + 1; - mem += bi->real.size() + 1; - } + + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + BotInfo *bi = it->second; + + count++; + mem += sizeof(*bi); + mem += bi->nick.size() + 1; + mem += bi->user.size() + 1; + mem += bi->host.size() + 1; + mem += bi->real.size() + 1; } *nrec = count; @@ -78,46 +71,21 @@ void bs_init() /* Main BotServ routine. */ -void botserv(User * u, char *buf) +void botserv(User *u, BotInfo *bi, const std::string &buf) { - char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) { + if (!u || !bi || buf.empty()) return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(findbot(Config.s_BotServ), u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(Config.s_BotServ, u, BOTSERV, cmd); - } - -} - -/*************************************************************************/ - -/* Handles all messages sent to bots. (Currently only answers to pings ;) */ - -void botmsgs(User * u, BotInfo * bi, char *buf) -{ - char *cmd = strtok(buf, " "); - char *s; - - if (!cmd || !u) - return; - - if (!stricmp(cmd, "\1PING")) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(bi, u->nick.c_str(), "PING %s", s); + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(bi, u->nick.c_str(), "%s", command.c_str()); } - else if (cmd && bi->cmdTable) + else { - mod_run_cmd(bi->nick, u, bi->cmdTable, cmd); + mod_run_cmd(bi, u, buf); } } @@ -128,33 +96,36 @@ void botmsgs(User * u, BotInfo * bi, char *buf) * */ -void botchanmsgs(User * u, ChannelInfo * ci, char *buf) +void botchanmsgs(User *u, ChannelInfo *ci, const std::string &buf) { - int c; - char *cmd; - UserData *ud; - bool was_action = false; - Command *command; - std::string bbuf; - - if (!u || !buf || !ci || !ci->c) + if (!u || !ci || !ci->c || buf.empty()) return; - - /* Answer to ping if needed, without breaking the buffer. */ - if (!strnicmp(buf, "\1PING", 5)) { - ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "PING %s", buf); + + /* Answer to ping if needed */ + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string ctcp = buf; + ctcp.erase(ctcp.begin()); + ctcp.erase(ctcp.end()); + ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "%s", ctcp.c_str()); } - /* If it's a /me, cut the CTCP part at the beginning (not - * at the end, because one character just doesn't matter, - * but the ACTION may create strange behaviours with the - * caps or badwords kickers */ - if (!strnicmp(buf, "\1ACTION ", 8)) + bool was_action = false; + std::string realbuf = buf; + + /* If it's a /me, cut the CTCP part because the ACTION will cause + * problems with the caps or badwords kicker + */ + if (realbuf.find("\1ACTION ", 0, 8) && realbuf[buf.length() - 1] == '\1') { - buf += 8; + realbuf.erase(0, 8); + realbuf.erase(realbuf.end()); was_action = true; } + if (realbuf.empty()) + return; + /* Now we can make kicker stuff. We try to order the checks * from the fastest one to the slowest one, since there's * no need to process other kickers if an user is kicked before @@ -172,56 +143,61 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE)) Allow = true; - if (buf && !check_access(u, ci, CA_NOKICK) && Allow) + if (!check_access(u, ci, CA_NOKICK) && Allow) { /* Bolds kicker */ - if (ci->botflags.HasFlag(BS_KICK_BOLDS) && strchr(buf, 2)) { + if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find_first_of(2) != std::string::npos) + { check_ban(ci, u, TTB_BOLDS); bot_kick(ci, u, BOT_REASON_BOLD); return; } /* Color kicker */ - if (ci->botflags.HasFlag(BS_KICK_COLORS) && strchr(buf, 3)) { + if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find_first_of(3) != std::string::npos) + { check_ban(ci, u, TTB_COLORS); bot_kick(ci, u, BOT_REASON_COLOR); return; } /* Reverses kicker */ - if (ci->botflags.HasFlag(BS_KICK_REVERSES) && strchr(buf, 22)) { + if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find_first_of(22) != std::string::npos) + { check_ban(ci, u, TTB_REVERSES); bot_kick(ci, u, BOT_REASON_REVERSE); return; } /* Underlines kicker */ - if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && strchr(buf, 31)) { + if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find_first_of(31) != std::string::npos) + { check_ban(ci, u, TTB_UNDERLINES); bot_kick(ci, u, BOT_REASON_UNDERLINE); return; } /* Caps kicker */ - if (ci->botflags.HasFlag(BS_KICK_CAPS) - && ((c = strlen(buf)) >= ci->capsmin)) { + if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->capsmin) + { int i = 0; int l = 0; - char *s = buf; - - do { - if (isupper(*s)) - i++; - else if (islower(*s)) - l++; - } while (*s++); + for (unsigned j = 0; j < realbuf.length(); ++j) + { + if (isupper(realbuf[j])) + ++i; + else if (islower(realbuf[j])) + ++l; + } + /* i counts uppercase chars, l counts lowercase chars. Only * alphabetic chars (so islower || isupper) qualify for the * percentage of caps to kick for; the rest is ignored. -GD */ - if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) { + if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) + { check_ban(ci, u, TTB_CAPS); bot_kick(ci, u, BOT_REASON_CAPS); return; @@ -229,49 +205,42 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Bad words kicker */ - if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) { - int mustkick = 0; - char *nbuf; - BadWord *bw; + if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) + { + bool mustkick = false; /* Normalize the buffer */ - nbuf = normalizeBuffer(buf); + const char *nbuf = normalizeBuffer(realbuf.c_str()); for (unsigned i = 0; i < ci->GetBadWordCount(); ++i) { - bw = ci->GetBadWord(i); - - if (bw->type == BW_ANY - && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str())) - || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str())))) { - mustkick = 1; - } else if (bw->type == BW_SINGLE) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive && nbuf == bw->word) - || (!Config.BSCaseSensitive - && (!stricmp(nbuf, bw->word.c_str())))) { - mustkick = 1; - /* two next if are quite odd isn't it? =) */ - } else if ((strchr(nbuf, ' ') == nbuf + len) - && - ((Config.BSCaseSensitive && nbuf == bw->word) - || (!Config.BSCaseSensitive - && (stristr(nbuf, bw->word.c_str()) == - nbuf)))) { - mustkick = 1; - } else { - if ((strrchr(nbuf, ' ') == - nbuf + strlen(nbuf) - len - 1) - && - ((Config.BSCaseSensitive - && (strstr(nbuf, bw->word.c_str()) == - nbuf + strlen(nbuf) - len)) - || (!Config.BSCaseSensitive - && (stristr(nbuf, bw->word.c_str()) == - nbuf + strlen(nbuf) - len)))) { - mustkick = 1; - } else { + BadWord *bw = ci->GetBadWord(i); + + if (bw->type == BW_ANY && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str())) || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str())))) + { + mustkick = true; + } + else if (bw->type == BW_SINGLE) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && nbuf == bw->word) || (!Config.BSCaseSensitive && (!stricmp(nbuf, bw->word.c_str())))) + { + mustkick = true; + } + else if ((strchr(nbuf, ' ') == nbuf + len) && ((Config.BSCaseSensitive && nbuf == bw->word) + || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf)))) + { + mustkick = true; + } + else + { + if ((strrchr(nbuf, ' ') == nbuf + strlen(nbuf) - len - 1) && ((Config.BSCaseSensitive && (strstr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len)) || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 3]; wordbuf[0] = ' '; @@ -279,69 +248,67 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) wordbuf[len + 2] = '\0'; memcpy(wordbuf + 1, bw->word.c_str(), len); - if ((Config.BSCaseSensitive - && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) { - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; } - /* free previous (sc)allocated memory (#850) */ delete [] wordbuf; } } - } else if (bw->type == BW_START) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive - && (!strncmp(nbuf, bw->word.c_str(), len))) - || (!Config.BSCaseSensitive - && (!strnicmp(nbuf, bw->word.c_str(), len)))) { - mustkick = 1; - } else { + } + else if (bw->type == BW_START) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && (!strncmp(nbuf, bw->word.c_str(), len))) || (!Config.BSCaseSensitive && (!strnicmp(nbuf, bw->word.c_str(), len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 2]; memcpy(wordbuf + 1, bw->word.c_str(), len); wordbuf[0] = ' '; wordbuf[len + 1] = '\0'; - if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; + } delete [] wordbuf; } - } else if (bw->type == BW_END) { - int len = bw->word.length(); - - if ((Config.BSCaseSensitive - && - (!strncmp - (nbuf + strlen(nbuf) - len, bw->word.c_str(), len))) - || (!Config.BSCaseSensitive - && - (!strnicmp - (nbuf + strlen(nbuf) - len, bw->word.c_str(), - len)))) { - mustkick = 1; - } else { + } + else if (bw->type == BW_END) + { + size_t len = bw->word.length(); + + if ((Config.BSCaseSensitive && (!strncmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len))) + || (!Config.BSCaseSensitive && (!strnicmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len)))) + { + mustkick = true; + } + else + { char *wordbuf = new char[len + 2]; memcpy(wordbuf, bw->word.c_str(), len); wordbuf[len] = ' '; wordbuf[len + 1] = '\0'; - if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) - || (!Config.BSCaseSensitive - && (stristr(nbuf, wordbuf)))) - mustkick = 1; + if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf)))) + { + mustkick = true; + } delete [] wordbuf; } } - if (mustkick) { + if (mustkick) + { check_ban(ci, u, TTB_BADWORDS); if (Config.BSGentleBWReason) bot_kick(ci, u, BOT_REASON_BADWORD_GENTLE); @@ -360,21 +327,23 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Flood kicker */ - if (ci->botflags.HasFlag(BS_KICK_FLOOD)) { + if (ci->botflags.HasFlag(BS_KICK_FLOOD)) + { time_t now = time(NULL); - ud = get_user_data(ci->c, u); - if (!ud) { + UserData *ud = get_user_data(ci->c, u); + if (!ud) return; - } - if (now - ud->last_start > ci->floodsecs) { + if (now - ud->last_start > ci->floodsecs) + { ud->last_start = time(NULL); ud->lines = 0; } ud->lines++; - if (ud->lines >= ci->floodlines) { + if (ud->lines >= ci->floodlines) + { check_ban(ci, u, TTB_FLOOD); bot_kick(ci, u, BOT_REASON_FLOOD); return; @@ -382,22 +351,27 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } /* Repeat kicker */ - if (ci->botflags.HasFlag(BS_KICK_REPEAT)) { - ud = get_user_data(ci->c, u); - if (!ud) { + if (ci->botflags.HasFlag(BS_KICK_REPEAT)) + { + UserData *ud = get_user_data(ci->c, u); + if (!ud) return; - } - if (ud->lastline && stricmp(ud->lastline, buf)) { + + if (ud->lastline && stricmp(ud->lastline, buf.c_str())) + { delete [] ud->lastline; - ud->lastline = sstrdup(buf); + ud->lastline = sstrdup(buf.c_str()); ud->times = 0; - } else { + } + else + { if (!ud->lastline) - ud->lastline = sstrdup(buf); + ud->lastline = sstrdup(buf.c_str()); ud->times++; } - if (ud->times >= ci->repeattimes) { + if (ud->times >= ci->repeattimes) + { check_ban(ci, u, TTB_REPEAT); bot_kick(ci, u, BOT_REASON_REPEAT); return; @@ -405,31 +379,31 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) } } - /* return if the user is on the ignore list */ - if (get_ignore(u->nick.c_str()) != NULL) { + if (get_ignore(u->nick.c_str()) != NULL) + { return; } /* Fantaisist commands */ + if (ci->botflags.HasFlag(BS_FANTASY) && buf[0] == *Config.BSFantasyCharacter && !was_action) + { + spacesepstream sep(buf); + std::string token; - if (buf && ci->botflags.HasFlag(BS_FANTASY) && *buf == *Config.BSFantasyCharacter && !was_action) { - cmd = strtok(buf, " "); - - if (cmd && (cmd[0] == *Config.BSFantasyCharacter)) { - char *params = strtok(NULL, ""); - + if (sep.GetToken(token) && (token[0] == *Config.BSFantasyCharacter)) + { /* Strip off the fantasy character */ - cmd++; + token.erase(token.begin()); if (check_access(u, ci, CA_FANTASIA)) { - command = findCommand(CHANSERV, cmd); + Command *command = FindCommand(ChanServ, token.c_str()); /* Command exists and can not be called by fantasy */ if (command && !command->HasFlag(CFLAG_DISABLE_FANTASY)) { - bbuf = std::string(cmd); + std::string bbuf = std::string(token); /* Some commands don't need the channel name added.. eg !help */ if (!command->HasFlag(CFLAG_STRIP_CHANNEL)) @@ -438,20 +412,20 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) bbuf += ci->name; } - if (params) + if (!sep.StreamEnd()) { bbuf += " "; - bbuf += params; + bbuf += sep.GetRemaining(); } - chanserv(u, const_cast<char *>(bbuf.c_str())); // XXX Unsafe cast, this needs reviewing -- CyberBotX + chanserv(u, bbuf); } - FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(cmd, u, ci, params)); + FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(token, u, ci, sep.GetRemaining())); } else { - FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(cmd, u, ci, params)); + FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(token, u, ci, sep.GetRemaining())); } } } @@ -459,53 +433,31 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) /*************************************************************************/ -/* Inserts a bot in the bot list. I can't be much explicit mh? */ - -void insert_bot(BotInfo *bi) +BotInfo *findbot(const char *nick) { - BotInfo *ptr, *prev; - - ci::string ci_bi_nick(bi->nick.c_str()); - for (prev = NULL, ptr = botlists[tolower(bi->nick[0])]; - ptr != NULL && ci_bi_nick > ptr->nick.c_str(); - prev = ptr, ptr = ptr->next); - bi->prev = prev; - bi->next = ptr; - if (!prev) - botlists[tolower(bi->nick[0])] = bi; - else - prev->next = bi; - if (ptr) - ptr->prev = bi; + return findbot(ci::string(nick)); } -/*************************************************************************/ -/*************************************************************************/ - BotInfo *findbot(const std::string &nick) { - BotInfo *bi; - - if (nick.empty()) - return NULL; - - ci::string ci_nick(nick.c_str()); + return findbot(ci::string(nick.c_str())); +} - /* - * XXX Less than efficient, but we need to do this for good TS6 support currently. This *will* improve. -- w00t - */ - for (int i = 0; i < 256; i++) +BotInfo *findbot(const ci::string &nick) +{ + if (isdigit(nick[0]) && ircd->ts6) { - for (bi = botlists[i]; bi; bi = bi->next) - { - if (ci_nick == bi->nick) - return bi; + botinfo_uid_map::const_iterator it = BotListByUID.find(nick.c_str()); - if (ci_nick == bi->uid) - return bi; - } + if (it != BotListByUID.end()) + return it->second; + return NULL; } + botinfo_map::const_iterator it = BotListByNick.find(nick); + + if (it != BotListByNick.end()) + return it->second; return NULL; } @@ -665,7 +617,7 @@ static void check_ban(ChannelInfo *ci, User *u, int ttbtype) return; /* Don't ban ulines */ - if (is_ulined(u->server->name)) + if (u->server->IsULined()) return; bd->ttb[ttbtype]++; @@ -723,7 +675,7 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, const char *rea if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) { - if (is_protected(u) && (requester != u)) { + if (u->IsProtected() && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED)); return; } @@ -764,7 +716,7 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, const char *re if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) { - if (is_protected(u) && (requester != u)) { + if (u->IsProtected() && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED)); return; } @@ -797,7 +749,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, char *ni snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL))); if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) { - if (is_protected(u) && *mode == '-' && (requester != u)) { + if (u->IsProtected() && *mode == '-' && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED)); return; } diff --git a/src/channels.c b/src/channels.cpp index b98a2f579..b2c839083 100644 --- a/src/channels.c +++ b/src/channels.cpp @@ -15,11 +15,7 @@ #include "language.h" #include "modules.h" -Channel *chanlist[1024]; - -#define HASH(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0) - -/*************************************************************************/ +channel_map ChannelList; /** Default constructor * @param name The channel name @@ -27,18 +23,12 @@ Channel *chanlist[1024]; */ Channel::Channel(const std::string &name, time_t ts) { - Channel **list; - if (name.empty()) throw CoreException("A channel without a name ?"); this->name = name; - list = &chanlist[HASH(this->name)]; - this->prev = NULL; - this->next = *list; - if (*list) - (*list)->prev = this; - *list = this; + + ChannelList[this->name.c_str()] = this; this->creation_time = ts; this->topic = NULL; @@ -102,12 +92,7 @@ Channel::~Channel() } } - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - chanlist[HASH(this->name)] = this->next; + ChannelList.erase(this->name.c_str()); } void Channel::Sync() @@ -118,7 +103,7 @@ void Channel::Sync() stick_all(this->ci); } - if (serv_uplink && is_sync(serv_uplink) && !this->topic_sync) + if (Me && Me->IsSynced() && !this->topic_sync) restore_topic(name.c_str()); } @@ -146,7 +131,7 @@ void Channel::JoinUser(User *user) } /* Added channelname to entrymsg - 30.03.2004, Certus */ /* Also, don't send the entrymsg when bursting -GD */ - if (this->ci && this->ci->entry_message && is_sync(user->server)) + if (this->ci && this->ci->entry_message && user->server->IsSynced()) user->SendMessage(whosends(this->ci)->nick, "[%s] %s", this->name.c_str(), this->ci->entry_message); } @@ -158,7 +143,7 @@ void Channel::JoinUser(User *user) * But don't join the bot if the channel is persistant - Adam * But join persistant channels when syncing with our uplink- DP **/ - if (Config.s_BotServ && this->ci && this->ci->bi && ((serv_uplink->sync == SSYNC_IN_PROGRESS) || !this->ci->HasFlag(CI_PERSIST))) + if (Config.s_BotServ && this->ci && this->ci->bi && (!Me->IsSynced() || !this->ci->HasFlag(CI_PERSIST))) { if (this->users.size() == Config.BSMinUsers) bot_join(this->ci); @@ -172,7 +157,7 @@ void Channel::JoinUser(User *user) * to has synced, or we'll get greet-floods when the net * recovers from a netsplit. -GD */ - if (is_sync(user->server)) + if (user->server->IsSynced()) { ircdproto->SendPrivmsg(this->ci->bi, this->name.c_str(), "[%s] %s", user->Account()->display, user->Account()->greet); this->ci->bi->lastmsg = time(NULL); @@ -286,7 +271,7 @@ bool Channel::HasUserStatus(User *u, ChannelModeName Name) */ bool Channel::HasMode(ChannelModeName Name) { - return modes[Name]; + return modes.HasFlag(Name); } /** Set a mode internally on a channel, this is not sent out to the IRCd @@ -349,7 +334,7 @@ void Channel::SetModeInternal(ChannelMode *cm, const std::string ¶m, bool En return; } - modes[cm->Name] = true; + modes.SetFlag(cm->Name); if (!param.empty()) { @@ -491,7 +476,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const std::string ¶m, bool return; } - modes[cm->Name] = false; + modes.UnsetFlag(cm->Name); if (cm->Type == MODE_PARAM) { @@ -734,7 +719,7 @@ void Channel::ClearModes(BotInfo *bi) } } - modes.reset(); + modes.ClearFlags(); } /** Clear all the bans from the channel @@ -975,7 +960,11 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) va_end(args); /* May not kick ulines */ - if (is_ulined(u->server->name)) + if (u->server->IsULined()) + return false; + + /* Do not kick protected clients */ + if (u->IsProtected()) return false; EventReturn MOD_RESULT; @@ -1047,61 +1036,23 @@ char *chan_get_modes(Channel * chan, int complete, int plus) /*************************************************************************/ -/* Return the Channel structure corresponding to the named channel, or NULL - * if the channel was not found. chan is assumed to be non-NULL and valid - * (i.e. pointing to a channel name of 2 or more characters). */ - Channel *findchan(const char *chan) { - Channel *c; - - if (!chan || !*chan) - { - Alog(LOG_DEBUG) << "findchan() called with NULL values"; - return NULL; - } - - c = chanlist[HASH(chan)]; - while (c) - { - if (stricmp(c->name.c_str(), chan) == 0) - { - Alog(LOG_DEBUG_3) << "findchan(" << chan << ") -> " << static_cast<void *>(c); - return c; - } - c = c->next; - } - return NULL; + return findchan(ci::string(chan)); } -/*************************************************************************/ - -/* Iterate over all channels in the channel list. Return NULL at end of - * list. - */ - -static Channel *current; -static int next_index; - -Channel *firstchan() +Channel *findchan(const std::string &chan) { - next_index = 0; - while (next_index < 1024 && current == NULL) - current = chanlist[next_index++]; - Alog(LOG_DEBUG_3) << "firstchan() returning " << (current ? current->name : "NULL (end of list)"); - return current; + return findchan(ci::string(chan.c_str())); } -Channel *nextchan() +Channel *findchan(const ci::string &chan) { - if (current) - current = current->next; - if (!current && next_index < 1024) { - while (next_index < 1024 && current == NULL) - current = chanlist[next_index++]; - } - Alog(LOG_DEBUG_3) << "nextchan() returning " << (current ? current->name : "NULL (end of list)"); - return current; + channel_map::const_iterator it = ChannelList.find(chan); + + if (it != ChannelList.end()) + return it->second; + return NULL; } /*************************************************************************/ @@ -1111,40 +1062,39 @@ Channel *nextchan() void get_channel_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - Channel *chan; BanData *bd; - int i; std::string buf; - for (i = 0; i < 1024; i++) { - for (chan = chanlist[i]; chan; chan = chan->next) { - count++; - mem += sizeof(*chan); - if (chan->topic) - mem += strlen(chan->topic) + 1; - if (chan->GetParam(CMODE_KEY, buf)) - mem += buf.length() + 1; - if (chan->GetParam(CMODE_FLOOD, buf)) - mem += buf.length() + 1; - if (chan->GetParam(CMODE_REDIRECT, buf)) - mem += buf.length() + 1; - mem += get_memuse(chan->bans); - if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) - mem += get_memuse(chan->excepts); - if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) - mem += get_memuse(chan->invites); - for (CUserList::iterator it = chan->users.begin(); it != chan->users.end(); ++it) - { - mem += sizeof(*it); - mem += sizeof((*it)->ud); - if ((*it)->ud.lastline) - mem += strlen((*it)->ud.lastline) + 1; - } - for (bd = chan->bd; bd; bd = bd->next) { - if (bd->mask) - mem += strlen(bd->mask) + 1; - mem += sizeof(*bd); - } + for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit) + { + Channel *chan = cit->second; + + count++; + mem += sizeof(*chan); + if (chan->topic) + mem += strlen(chan->topic) + 1; + if (chan->GetParam(CMODE_KEY, buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_FLOOD, buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_REDIRECT, buf)) + mem += buf.length() + 1; + mem += get_memuse(chan->bans); + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + mem += get_memuse(chan->excepts); + if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) + mem += get_memuse(chan->invites); + for (CUserList::iterator it = chan->users.begin(); it != chan->users.end(); ++it) + { + mem += sizeof(*it); + mem += sizeof((*it)->ud); + if ((*it)->ud.lastline) + mem += strlen((*it)->ud.lastline) + 1; + } + for (bd = chan->bd; bd; bd = bd->next) { + if (bd->mask) + mem += strlen(bd->mask) + 1; + mem += sizeof(*bd); } } *nrec = count; @@ -1205,13 +1155,13 @@ void do_join(const char *source, int ac, const char **av) std::string channame = cc->chan->name; FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan)); cc->chan->DeleteUser(user); - FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame.c_str()), channame, "")); + FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame), channame, "")); } user->chans.clear(); continue; } - chan = findchan(buf.c_str()); + chan = findchan(buf); /* Channel doesn't exist, create it */ if (!chan) @@ -1306,7 +1256,7 @@ void do_part(const char *source, int ac, const char **av) ci::string buf; while (sep.GetToken(buf)) { - Channel *c = findchan(buf.c_str()); + Channel *c = findchan(buf); if (!c) { @@ -1320,7 +1270,7 @@ void do_part(const char *source, int ac, const char **av) FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, c)); std::string ChannelName = c->name; c->DeleteUser(user); - FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName.c_str()), ChannelName, av[1] ? av[1] : "")); + FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName), ChannelName, av[1] ? av[1] : "")); } else Alog(LOG_DEBUG) << "Recieved PART from " << user->nick << " for " << c->name << ", but " << user->nick << " isn't in " << c->name << "?"; @@ -1513,9 +1463,9 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) c->SetMode(NULL, CMODE_VOICE, user->nick); } /* If this channel has secureops or the user matches autodeop or the channel is syncing and this is the first user and they are not ulined, check to remove modes */ - if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !is_ulined(user->server->name)) + if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !user->server->IsULined()) { - if (owner && c->HasUserStatus(user, CMODE_OWNER) && !IsFounder(user, ci)) + if (owner && c->HasUserStatus(user, CMODE_OWNER) && !check_access(user, ci, CA_FOUNDER)) c->RemoveMode(NULL, CMODE_OWNER, user->nick); if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME)) @@ -1538,10 +1488,10 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) */ void MassChannelModes(BotInfo *bi, const std::string &modes) { - Channel *c; - - for (c = firstchan(); c; c = nextchan()) + for (channel_map::const_iterator it = ChannelList.begin(); it != ChannelList.end(); ++it) { + Channel *c = it->second; + if (c->bouncy_modes) return; c->SetModes(bi, false, modes.c_str()); @@ -1552,9 +1502,10 @@ void MassChannelModes(BotInfo *bi, const std::string &modes) void restore_unsynced_topics() { - Channel *c; + for (channel_map::const_iterator it = ChannelList.begin(); it != ChannelList.end(); ++it) + { + Channel *c = it->second; - for (c = firstchan(); c; c = nextchan()) { if (!(c->topic_sync)) restore_topic(c->name.c_str()); } diff --git a/src/chanserv.c b/src/chanserv.cpp index 377a04323..10acd3731 100644 --- a/src/chanserv.c +++ b/src/chanserv.cpp @@ -14,12 +14,10 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" +#include "language.h" -/*************************************************************************/ -/* *INDENT-OFF* */ - -ChannelInfo *chanlists[256]; +registered_channel_map RegisteredChannelList; static int def_levels[][2] = { { CA_AUTOOP, 5 }, @@ -61,6 +59,7 @@ static int def_levels[][2] = { { CA_AUTOOWNER, ACCESS_QOP }, { CA_OWNER, ACCESS_FOUNDER }, { CA_OWNERME, ACCESS_QOP }, + { CA_FOUNDER, ACCESS_QOP }, { -1 } }; @@ -105,6 +104,7 @@ LevelInfo levelinfo[] = { { CA_AUTOOWNER, "AUTOOWNER", CHAN_LEVEL_AUTOOWNER }, { CA_OWNER, "OWNER", CHAN_LEVEL_OWNER }, { CA_OWNERME, "OWNERME", CHAN_LEVEL_OWNERME }, + { CA_FOUNDER, "FOUNDER", CHAN_LEVEL_FOUNDER }, { -1 } }; int levelinfo_maxwidth = 0; @@ -195,51 +195,51 @@ char *get_mlock_modes(ChannelInfo * ci, int complete) void get_chanserv_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - unsigned i, j; - ChannelInfo *ci; std::string param; - for (i = 0; i < 256; i++) { - for (ci = chanlists[i]; ci; ci = ci->next) { - count++; - mem += sizeof(*ci); - if (ci->desc) - mem += strlen(ci->desc) + 1; - if (ci->url) - mem += strlen(ci->url) + 1; - if (ci->email) - mem += strlen(ci->email) + 1; - mem += ci->GetAccessCount() * sizeof(ChanAccess); - mem += ci->GetAkickCount() * sizeof(AutoKick); - - if (ci->GetParam(CMODE_KEY, param)) - mem += param.length() + 1; - - if (ci->GetParam(CMODE_FLOOD, param)) - mem += param.length() + 1; - - if (ci->GetParam(CMODE_REDIRECT, param)) - mem += param.length() + 1; - - if (ci->last_topic) - mem += strlen(ci->last_topic) + 1; - if (ci->entry_message) - mem += strlen(ci->entry_message) + 1; - if (ci->forbidby) - mem += strlen(ci->forbidby) + 1; - if (ci->forbidreason) - mem += strlen(ci->forbidreason) + 1; - if (ci->levels) - mem += sizeof(*ci->levels) * CA_SIZE; - mem += ci->memos.memos.size() * sizeof(Memo); - for (j = 0; j < ci->memos.memos.size(); j++) { - if (ci->memos.memos[j]->text) - mem += strlen(ci->memos.memos[j]->text) + 1; - } - if (ci->ttb) - mem += sizeof(*ci->ttb) * TTB_SIZE; - mem += ci->GetBadWordCount() * sizeof(BadWord); + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; + + count++; + mem += sizeof(*ci); + if (ci->desc) + mem += strlen(ci->desc) + 1; + if (ci->url) + mem += strlen(ci->url) + 1; + if (ci->email) + mem += strlen(ci->email) + 1; + mem += ci->GetAccessCount() * sizeof(ChanAccess); + mem += ci->GetAkickCount() * sizeof(AutoKick); + + if (ci->GetParam(CMODE_KEY, param)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_FLOOD, param)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_REDIRECT, param)) + mem += param.length() + 1; + + if (ci->last_topic) + mem += strlen(ci->last_topic) + 1; + if (ci->entry_message) + mem += strlen(ci->entry_message) + 1; + if (ci->forbidby) + mem += strlen(ci->forbidby) + 1; + if (ci->forbidreason) + mem += strlen(ci->forbidreason) + 1; + if (ci->levels) + mem += sizeof(*ci->levels) * CA_SIZE; + mem += ci->memos.memos.size() * sizeof(Memo); + for (unsigned j = 0; j < ci->memos.memos.size(); j++) + { + if (ci->memos.memos[j]->text) + mem += strlen(ci->memos.memos[j]->text) + 1; } + if (ci->ttb) + mem += sizeof(*ci->ttb) * TTB_SIZE; + mem += ci->GetBadWordCount() * sizeof(BadWord); } *nrec = count; *memuse = mem; @@ -259,21 +259,21 @@ void cs_init() /* Main ChanServ routine. */ -void chanserv(User * u, char *buf) +void chanserv(User *u, const std::string &buf) { - char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) { + if (!u || buf.empty()) return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - *s = 0; - } - ircdproto->SendCTCP(findbot(Config.s_ChanServ), u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(Config.s_ChanServ, u, CHANSERV, cmd); + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(ChanServ, u->nick.c_str(), "%s", command.c_str()); + } + else + { + mod_run_cmd(ChanServ, u, buf); } } @@ -468,111 +468,6 @@ int check_valid_op(User * user, Channel * chan, int servermode) /*************************************************************************/ -/* Check whether a user should be opped on a channel, and if so, do it. - * Return 1 if the user was opped, 0 otherwise. (Updates the channel's - * last used time if the user was opped.) */ - -int check_should_op(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified()) - return 0; - - if (check_access(user, ci, CA_AUTOOP)) - { - ci->c->SetMode(NULL, CMODE_OP, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -/* Check whether a user should be voiced on a channel, and if so, do it. - * Return 1 if the user was voiced, 0 otherwise. */ - -int check_should_voice(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified()) - return 0; - - if (check_access(user, ci, CA_AUTOVOICE)) - { - ci->c->SetMode(NULL, CMODE_VOICE, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_halfop(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+') - return 0; - - if (check_access(user, ci, CA_AUTOHALFOP)) - { - ci->c->SetMode(NULL, CMODE_HALFOP, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_owner(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+') - return 0; - - if ((ci->HasFlag(CI_SECUREFOUNDER) && IsRealFounder(user, ci)) - || (!ci->HasFlag(CI_SECUREFOUNDER) && IsFounder(user, ci))) { - ci->c->SetMode(NULL, CMODE_OP, user->nick); - ci->c->SetMode(NULL, CMODE_OWNER, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - -int check_should_protect(User * user, char *chan) -{ - ChannelInfo *ci = cs_findchan(chan); - - if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+') - return 0; - - if (check_access(user, ci, CA_AUTOPROTECT)) - { - ci->c->SetMode(NULL, CMODE_OWNER, user->nick); - ci->c->SetMode(NULL, CMODE_PROTECT, user->nick); - return 1; - } - - return 0; -} - -/*************************************************************************/ - /* Record the current channel topic in the ChannelInfo structure. */ void record_topic(const char *chan) @@ -632,15 +527,15 @@ void restore_topic(const char *chan) c->topic_setter = whosends(ci)->nick; } if (ircd->join2set) { - if (whosends(ci) == findbot(Config.s_ChanServ)) { - ircdproto->SendJoin(findbot(Config.s_ChanServ), chan, c->creation_time); + if (whosends(ci) == ChanServ) { + ircdproto->SendJoin(ChanServ, chan, c->creation_time); c->SetMode(NULL, CMODE_OP, Config.s_ChanServ); } } ircdproto->SendTopic(whosends(ci), c, c->topic_setter.c_str(), c->topic ? c->topic : ""); if (ircd->join2set) { - if (whosends(ci) == findbot(Config.s_ChanServ)) { - ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL); + if (whosends(ci) == ChanServ) { + ircdproto->SendPart(ChanServ, c, NULL); } } } @@ -692,8 +587,8 @@ int check_topiclock(Channel * c, time_t topic_time) } if (ircd->join2set) { - if (whosends(ci) == findbot(Config.s_ChanServ)) { - ircdproto->SendJoin(findbot(Config.s_ChanServ), c->name.c_str(), c->creation_time); + if (whosends(ci) == ChanServ) { + ircdproto->SendJoin(ChanServ, c->name.c_str(), c->creation_time); c->SetMode(NULL, CMODE_OP, Config.s_ChanServ); } } @@ -701,8 +596,8 @@ int check_topiclock(Channel * c, time_t topic_time) ircdproto->SendTopic(whosends(ci), c, c->topic_setter.c_str(), c->topic ? c->topic : ""); if (ircd->join2set) { - if (whosends(ci) == findbot(Config.s_ChanServ)) { - ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL); + if (whosends(ci) == ChanServ) { + ircdproto->SendPart(ChanServ, c, NULL); } } return 1; @@ -714,118 +609,113 @@ int check_topiclock(Channel * c, time_t topic_time) void expire_chans() { - ChannelInfo *ci, *next; - int i; - time_t now = time(NULL); - if (!Config.CSExpire) return; + + time_t now = time(NULL); - for (i = 0; i < 256; i++) { - for (ci = chanlists[i]; ci; ci = next) { - next = ci->next; - if (!ci->c && now - ci->last_used >= Config.CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED)) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci)); - if (MOD_RESULT == EVENT_STOP) - continue; + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end();) + { + ChannelInfo *ci = it->second; + ++it; - char *chname = sstrdup(ci->name.c_str()); - Alog() << "Expiring channel " << ci->name << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << " )"; - delete ci; - FOREACH_MOD(I_OnChanExpire, OnChanExpire(chname)); - delete [] chname; - } + if (!ci->c && now - ci->last_used >= Config.CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED)) + { + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci)); + if (MOD_RESULT == EVENT_STOP) + continue; + + char *chname = sstrdup(ci->name.c_str()); + Alog() << "Expiring channel " << ci->name << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << " )"; + delete ci; + FOREACH_MOD(I_OnChanExpire, OnChanExpire(chname)); + delete [] chname; } } } /*************************************************************************/ -/* Remove a (deleted or expired) nickname from all channel lists. */ - +// XXX this is slightly inefficient void cs_remove_nick(const NickCore * nc) { - int i, j; - ChannelInfo *ci, *next; + int j; ChanAccess *ca; AutoKick *akick; - for (i = 0; i < 256; i++) { - for (ci = chanlists[i]; ci; ci = next) { - next = ci->next; - if (ci->founder == nc) { - if (ci->successor) { - NickCore *nc2 = ci->successor; - if (!nc2->IsServicesOper() && Config.CSMaxReg && nc2->channelcount >= Config.CSMaxReg) { - Alog() << Config.s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel", - delete ci; - continue; - } else { - Alog() << Config.s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display; - ci->founder = nc2; - ci->successor = NULL; - nc2->channelcount++; - } + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; + + if (ci->founder == nc) { + if (ci->successor) { + NickCore *nc2 = ci->successor; + if (!nc2->IsServicesOper() && Config.CSMaxReg && nc2->channelcount >= Config.CSMaxReg) { + Alog() << Config.s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel", + delete ci; + continue; } else { - Alog() << Config.s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display; + Alog() << Config.s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display; + ci->founder = nc2; + ci->successor = NULL; + nc2->channelcount++; + } + } else { + Alog() << Config.s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display; - if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED))) + if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED))) + { + /* Maybe move this to delchan() ? */ + if (ci->c && ci->c->HasMode(CMODE_REGISTERED)) { - /* Maybe move this to delchan() ? */ - if (ci->c && ci->c->HasMode(CMODE_REGISTERED)) - { - ci->c->RemoveMode(NULL, CMODE_REGISTERED); - } + ci->c->RemoveMode(NULL, CMODE_REGISTERED); } - - delete ci; - continue; } + + delete ci; + continue; } + } - if (ci->successor == nc) - ci->successor = NULL; + if (ci->successor == nc) + ci->successor = NULL; - for (j = ci->GetAccessCount(); j > 0; --j) - { - ca = ci->GetAccess(j - 1); + for (j = ci->GetAccessCount(); j > 0; --j) + { + ca = ci->GetAccess(j - 1); - if (ca->in_use && ca->nc == nc) - ci->EraseAccess(j - 1); - } + if (ca->nc == nc) + ci->EraseAccess(j - 1); + } - for (j = ci->GetAkickCount(); j > 0; --j) - { - akick = ci->GetAkick(j - 1); - if (akick->InUse && akick->HasFlag(AK_ISNICK) && akick->nc == nc) - ci->EraseAkick(akick); - } + for (j = ci->GetAkickCount(); j > 0; --j) + { + akick = ci->GetAkick(j - 1); + if (akick->HasFlag(AK_ISNICK) && akick->nc == nc) + ci->EraseAkick(j - 1); } } } /*************************************************************************/ -/* Return the ChannelInfo structure for the given channel, or NULL if the - * channel isn't registered. */ +ChannelInfo *cs_findchan(const char *chan) +{ + return cs_findchan(ci::string(chan)); +} ChannelInfo *cs_findchan(const std::string &chan) { - ChannelInfo *ci; + return cs_findchan(ci::string(chan.c_str())); +} - if (chan.empty()) - { - Alog(LOG_DEBUG) << "cs_findchan() called with NULL values"; - return NULL; - } +ChannelInfo *cs_findchan(const ci::string &chan) +{ + registered_channel_map::const_iterator it = RegisteredChannelList.find(chan); - for (ci = chanlists[static_cast<unsigned char>(tolower(chan[1]))]; ci; - ci = ci->next) { - if (ci::string(ci->name.c_str()) == chan) - return ci; - } + if (it != RegisteredChannelList.end()) + return it->second; return NULL; } @@ -853,15 +743,20 @@ int check_access(User * user, ChannelInfo * ci, int what) if (level > 0) ci->last_used = time(NULL); + /* Superadmin always wins. Always. */ + if (user->isSuperAdmin) + return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1); + /* If the access of the level we are checking is disabled, they *always* get denied */ if (limit == ACCESS_INVALID) return 0; - if (limit > ACCESS_FOUNDER) - return 1; - if (limit == ACCESS_FOUNDER) - return (what == CA_AUTODEOP || what == CA_NOJOIN ? !IsRealFounder(user, ci) : IsRealFounder(user, ci)); + /* If the level of the user is >= the level for "founder" of this channel and "founder" isn't disabled, they can do anything */ + if (ci->levels[CA_FOUNDER] != ACCESS_INVALID && level >= ci->levels[CA_FOUNDER]) + return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1); + /* Hacks to make flags work */ if (what == CA_AUTODEOP && (ci->HasFlag(CI_SECUREOPS)) && level == 0) return 1; + if (what == CA_AUTODEOP || what == CA_NOJOIN) return level <= ci->levels[what]; else @@ -872,33 +767,6 @@ int check_access(User * user, ChannelInfo * ci, int what) /*********************** ChanServ private routines ***********************/ /*************************************************************************/ -/* Insert a channel alphabetically into the database. */ - -void alpha_insert_chan(ChannelInfo * ci) -{ - ChannelInfo *ptr, *prev; - - if (!ci) - { - Alog(LOG_DEBUG) << "alpha_insert_chan() called with NULL values"; - return; - } - - const char *chan = ci->name.c_str(); - - for (prev = NULL, ptr = chanlists[static_cast<unsigned char>(tolower(chan[1]))]; - ptr != NULL && stricmp(ptr->name.c_str(), chan) < 0; - prev = ptr, ptr = ptr->next); - ci->prev = prev; - ci->next = ptr; - if (!prev) - chanlists[static_cast<unsigned char>(tolower(chan[1]))] = ci; - else - prev->next = ci; - if (ptr) - ptr->prev = ci; -} - /* Reset channel access level values to their default state. */ void reset_levels(ChannelInfo * ci) @@ -920,43 +788,12 @@ void reset_levels(ChannelInfo * ci) /*************************************************************************/ -/** Is the user a channel founder? (owner) - * @param user The user - * @param ci The channel - * @return true or false - */ -bool IsFounder(User *user, ChannelInfo *ci) -{ - ChanAccess *access = NULL; - - if (!user || !ci) - return false; - - if (IsRealFounder(user, ci)) - return true; - - if (user->Account()) - access = ci->GetAccess(user->Account()); - else - { - NickAlias *na = findnick(user->nick); - if (na) - access = ci->GetAccess(na->nc); - } - - /* If they're QOP+ and theyre identified or theyre recognized and the channel isn't secure */ - if (access && access->level >= ACCESS_QOP && (user->Account() || (user->IsRecognized() && !(ci->HasFlag(CI_SECURE))))) - return true; - - return false; -} - /** Is the user the real founder? * @param user The user * @param ci The channel * @return true or false */ -bool IsRealFounder(User *user, ChannelInfo *ci) +bool IsFounder(User *user, ChannelInfo *ci) { if (!user || !ci) return false; @@ -1088,6 +925,22 @@ int get_access_level(ChannelInfo * ci, NickAlias * na) return access->level; } +int get_access_level(ChannelInfo *ci, NickCore *nc) +{ + if (!ci || !nc) + return 0; + + if (nc == ci->founder) + return ACCESS_FOUNDER; + + ChanAccess *access = ci->GetAccess(nc); + + if (!access) + return 0; + else + return access->level; +} + const char *get_xop_level(int level) { ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); @@ -1125,7 +978,7 @@ AutoKick *is_stuck(ChannelInfo * ci, const char *mask) { AutoKick *akick = ci->GetAkick(i); - if (!akick->InUse || akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK)) + if (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK)) continue; if (Anope::Match(akick->mask, mask, false)) @@ -1180,7 +1033,7 @@ void stick_all(ChannelInfo * ci) { AutoKick *akick = ci->GetAkick(i); - if (!akick->InUse || (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK))) + if (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK)) continue; ci->c->SetMode(NULL, CMODE_BAN, akick->mask.c_str()); @@ -1204,7 +1057,7 @@ void ChanServTimer::Tick(time_t) if (!c->users.empty()) return; - ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL); + ircdproto->SendPart(ChanServ, c, NULL); /* Now delete the channel as it is empty */ if (!c->HasFlag(CH_PERSIST) && !c->ci->HasFlag(CI_PERSIST)) diff --git a/src/command.cpp b/src/command.cpp index ea66a7261..922f298c3 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -10,32 +10,41 @@ #include "services.h" #include "modules.h" -Command::Command(const std::string &sname, size_t min_params, size_t max_params, const std::string &spermission) : MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission) +Command::Command(const ci::string &sname, size_t min_params, size_t max_params, const std::string &spermission) : MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission) { - this->core = 0; - this->mod_name = NULL; + this->module = NULL; this->service = NULL; - this->next = NULL; } Command::~Command() { - if (this->mod_name) { - delete [] this->mod_name; - } - if (this->service) { - delete [] this->service; - } } -CommandReturn Command::Execute(User *u, const std::vector<ci::string> &) { return MOD_CONT; } +CommandReturn Command::Execute(User *u, const std::vector<ci::string> &) +{ + return MOD_CONT; +} + +void Command::OnServHelp(User *u) { } bool Command::OnHelp(User *u, const ci::string &subcommand) { return false; } -void Command::OnSyntaxError(User *u, const ci::string &subcommand) { } +void Command::OnSyntaxError(User *u, const ci::string &subcommand) +{ +} void Command::SetPermission(const std::string &reststr) { this->permission = reststr; } +bool Command::AddSubcommand(Command *c) +{ + return false; +} + +bool Command::DelSubcommand(const ci::string &cname) +{ + return false; +} + diff --git a/src/commands.c b/src/commands.cpp index 19d668137..f066b2885 100644 --- a/src/commands.c +++ b/src/commands.cpp @@ -12,55 +12,49 @@ */ #include "services.h" -#include "commands.h" +#include "modules.h" #include "language.h" #include "hashcomp.h" -/*************************************************************************/ +Command *FindCommand(BotInfo *bi, const ci::string &name) +{ + if (!bi || bi->Commands.empty() || name.empty()) + return NULL; + + std::map<ci::string, Command *>::iterator it = bi->Commands.find(name); -/** - * Return the Command corresponding to the given name, or NULL if no such - * command exists. - * @param list Command struct - * @param cmd Command to look up - * @return Command Struct for the given cmd - */ -Command *lookup_cmd(Command * list, char *cmd) + if (it != bi->Commands.end()) + return it->second; + + return NULL; +} + +void mod_run_cmd(BotInfo *bi, User *u, const std::string &message) { - Command *c; + spacesepstream sep(ci::string(message.c_str())); + ci::string cmd; - for (c = list; ; c++) { - if (stricmp(c->name.c_str(), cmd) == 0) { - return c; - } + if (sep.GetToken(cmd)) + { + mod_run_cmd(bi, u, FindCommand(bi, cmd), cmd, sep.GetRemaining().c_str()); } } -/*************************************************************************/ - -/** - * Run the routine for the given command, if it exists and the user has - * privilege to do so; if not, print an appropriate error message. - * @param services Services Client - * @param u User Struct - * @param Command Hash Table - * @param cmd Command - * @return void - */ -void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], const char *cmd) +void mod_run_cmd(BotInfo *bi, User *u, Command *c, const ci::string &command, const ci::string &message) { - Command *c = findCommand(cmdTable, cmd); - int retVal = MOD_CONT; - ChannelInfo *ci; - EventReturn MOD_RESULT; + if (!bi || !u) + return; + + CommandReturn ret = MOD_CONT; - FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(service, u, cmd, c)); + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(u, bi, command, message, c)); if (MOD_RESULT == EVENT_STOP) return; if (!c) { - notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service.c_str()); + notice_lang(bi->nick, u, UNKNOWN_COMMAND_HELP, command.c_str(), bi->nick.c_str()); return; } @@ -69,36 +63,36 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], // Command requires registered users only if (!u->IsIdentified()) { - notice_lang(service, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ); - Alog() << "Access denied for unregistered user " << u->nick << " with service " << service << " and command " << cmd; + notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ); + Alog() << "Access denied for unregistered user " << u->nick << " with service " << bi->nick << " and command " << command; return; } } std::vector<ci::string> params; - std::string curparam; - char *s = NULL; - while ((s = strtok(NULL, " "))) + ci::string curparam, endparam; + spacesepstream sep(message); + while (sep.GetToken(curparam)) { // - 1 because params[0] corresponds with a maxparam of 1. if (params.size() >= (c->MaxParams - 1)) { - curparam += s; - curparam += " "; + endparam += curparam; + endparam += " "; } else { - params.push_back(s); + params.push_back(curparam); } } - if (!curparam.empty()) + if (!endparam.empty()) { // Remove trailing space - curparam.erase(curparam.size() - 1, curparam.size()); + endparam.erase(endparam.size() - 1, endparam.size()); // Add it - params.push_back(curparam.c_str()); + params.push_back(endparam); } if (params.size() < c->MinParams) @@ -107,41 +101,42 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], return; } - FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name.c_str(), params)); + FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name, params)); if (MOD_RESULT == EVENT_STOP) return; - if (params.size() > 0 && !c->HasFlag(CFLAG_STRIP_CHANNEL) && (cmdTable == CHANSERV || cmdTable == BOTSERV)) + if (params.size() > 0 && !c->HasFlag(CFLAG_STRIP_CHANNEL) && (bi == ChanServ || bi == BotServ)) { if (ircdproto->IsChannelValid(params[0].c_str())) { - if ((ci = cs_findchan(params[0].c_str()))) + ChannelInfo *ci = cs_findchan(params[0]); + if (ci) { if ((ci->HasFlag(CI_FORBIDDEN)) && (!c->HasFlag(CFLAG_ALLOW_FORBIDDEN))) { - notice_lang(service, u, CHAN_X_FORBIDDEN, ci->name.c_str()); - Alog() << "Access denied for user " << u->nick << " with service " << service - << " and command " << cmd << " because of FORBIDDEN channel " << ci->name; + notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); + Alog() << "Access denied for user " << u->nick << " with service " << bi->nick + << " and command " << command << " because of FORBIDDEN channel " << ci->name; return; } else if ((ci->HasFlag(CI_SUSPENDED)) && (!c->HasFlag(CFLAG_ALLOW_SUSPENDED))) { - notice_lang(service, u, CHAN_X_FORBIDDEN, ci->name.c_str()); - Alog() << "Access denied for user " << u->nick << " with service " << service - <<" and command " << cmd << " because of SUSPENDED channel " << ci->name; + notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str()); + Alog() << "Access denied for user " << u->nick << " with service " << bi->nick + <<" and command " << command << " because of SUSPENDED channel " << ci->name; return; } } else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL)) { - notice_lang(service, u, CHAN_X_NOT_REGISTERED, params[0].c_str()); + notice_lang(bi->nick, u, CHAN_X_NOT_REGISTERED, params[0].c_str()); return; } } /* A user not giving a channel name for a param that should be a channel */ else { - notice_lang(service, u, CHAN_X_INVALID, params[0].c_str()); + notice_lang(bi->nick, u, CHAN_X_INVALID, params[0].c_str()); return; } } @@ -151,23 +146,21 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], { if (!u->Account()->HasCommand(c->permission)) { - notice_lang(service, u, ACCESS_DENIED); - Alog() << "Access denied for user " << u->nick << " with service " << service << " and command " << cmd; + notice_lang(bi->nick, u, ACCESS_DENIED); + Alog() << "Access denied for user " << u->nick << " with service " << bi->nick << " and command " << command; return; } } - retVal = c->Execute(u, params); + ret = c->Execute(u, params); - if (retVal == MOD_CONT) + if (ret == MOD_CONT) { FOREACH_MOD(I_OnPostCommand, OnPostCommand(u, c->service, c->name.c_str(), params)); } } -/*************************************************************************/ - /** * Prints the help message for a given command. * @param services Services Client @@ -176,36 +169,38 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], * @param cmd Command * @return void */ -void mod_help_cmd(char *service, User * u, CommandHash * cmdTable[], const char *cmd) +void mod_help_cmd(BotInfo *bi, User *u, const ci::string &cmd) { + if (!bi || !u || cmd.empty()) + return; + spacesepstream tokens(cmd); - std::string token; + ci::string token; tokens.GetToken(token); - Command *c = findCommand(cmdTable, token.c_str()); + Command *c = FindCommand(bi, token); ci::string subcommand = tokens.StreamEnd() ? "" : tokens.GetRemaining().c_str(); if (!c || !c->OnHelp(u, subcommand)) - notice_lang(service, u, NO_HELP_AVAILABLE, cmd); + notice_lang(bi->nick, u, NO_HELP_AVAILABLE, cmd.c_str()); else { - u->SendMessage(service, " "); + u->SendMessage(bi->nick, " "); /* Inform the user what permission is required to use the command */ if (!c->permission.empty()) - notice_lang(service, u, COMMAND_REQUIRES_PERM, c->permission.c_str()); + notice_lang(bi->nick, u, COMMAND_REQUIRES_PERM, c->permission.c_str()); /* User isn't identified and needs to be to use this command */ if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) - notice_lang(service, u, COMMAND_IDENTIFY_REQUIRED); + notice_lang(bi->nick, u, COMMAND_IDENTIFY_REQUIRED); /* User doesn't have the proper permission to use this command */ else if (!c->permission.empty() && (!u->Account() || (!u->Account()->HasCommand(c->permission)))) - notice_lang(service, u, COMMAND_CANNOT_USE); + notice_lang(bi->nick, u, COMMAND_CANNOT_USE); /* User can use this command */ else - notice_lang(service, u, COMMAND_CAN_USE); + notice_lang(bi->nick, u, COMMAND_CAN_USE); } } -/*************************************************************************/ diff --git a/src/compat.c b/src/compat.cpp index eb3088fe9..eb3088fe9 100644 --- a/src/compat.c +++ b/src/compat.cpp diff --git a/src/config.c b/src/config.cpp index 9c486b7e3..a1264abce 100644 --- a/src/config.c +++ b/src/config.cpp @@ -12,7 +12,7 @@ */ #include "services.h" -#include "configreader.h" +#include "config.h" #include "hashcomp.h" // If this gets added to services.h or someplace else later, remove it from here -- CyberBotX /*************************************************************************/ @@ -425,8 +425,9 @@ static bool InitOperTypes(ServerConfig *, const char *, bool) static bool DoOperType(ServerConfig *conf, const char *, const char **, ValueList &values, int *, bool) { const char *name = values[0].GetString(); - const char *commands = values[1].GetString(); - const char *privs = values[2].GetString(); + const char *inherits = values[1].GetString(); + const char *commands = values[2].GetString(); + const char *privs = values[3].GetString(); ValueItem vi(name); if (!ValidateNotEmpty(conf, "opertype", "name", vi)) @@ -442,6 +443,23 @@ static bool DoOperType(ServerConfig *conf, const char *, const char **, ValueLis spacesepstream privstr(privs); while (privstr.GetToken(tok)) ot->AddPriv(tok); + + commasepstream inheritstr(inherits); + while (inheritstr.GetToken(tok)) + { + /* Strip leading ' ' after , */ + if (tok.size() > 1 && tok[0] == ' ') + tok.erase(tok.begin()); + for (std::list<OperType *>::iterator it = Config.MyOperTypes.begin(); it != Config.MyOperTypes.end(); ++it) + { + if ((*it)->GetName() == tok) + { + Alog() << "Inheriting commands and privs from " << (*it)->GetName() << " to " << ot->GetName(); + ot->Inherits(*it); + break; + } + } + } Config.MyOperTypes.push_back(ot); return true; @@ -456,13 +474,9 @@ static bool DoneOperTypes(ServerConfig *, const char *, bool) static bool InitOpers(ServerConfig *, const char *, bool) { - int i; - NickCore *nc; + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) + it->second->ot = NULL; - for (i = 0; i < 1024; ++i) - for (nc = nclists[i]; nc; nc = nc->next) - nc->ot = NULL; - Config.Opers.clear(); return true; @@ -724,11 +738,11 @@ int ServerConfig::Read(bool bail) {"operserv", "logmaxusers", "no", new ValueContainerBool(&Config.LogMaxUsers), DT_BOOLEAN, NoValidation}, {"operserv", "autokillexpiry", "0", new ValueContainerTime(&Config.AutokillExpiry), DT_TIME, ValidateNotZero}, {"operserv", "chankillexpiry", "0", new ValueContainerTime(&Config.ChankillExpiry), DT_TIME, ValidateNotZero}, - {"operserv", "sglineexpiry", "0", new ValueContainerTime(&Config.SGLineExpiry), DT_TIME, ValidateNotZero}, + {"operserv", "snlineexpiry", "0", new ValueContainerTime(&Config.SNLineExpiry), DT_TIME, ValidateNotZero}, {"operserv", "sqlineexpiry", "0", new ValueContainerTime(&Config.SQLineExpiry), DT_TIME, ValidateNotZero}, {"operserv", "szlineexpiry", "0", new ValueContainerTime(&Config.SZLineExpiry), DT_TIME, ValidateNotZero}, {"operserv", "akillonadd", "no", new ValueContainerBool(&Config.AkillOnAdd), DT_BOOLEAN, NoValidation}, - {"operserv", "killonsgline", "no", new ValueContainerBool(&Config.KillonSGline), DT_BOOLEAN, NoValidation}, + {"operserv", "killonsnline", "no", new ValueContainerBool(&Config.KillonSNline), DT_BOOLEAN, NoValidation}, {"operserv", "killonsqline", "no", new ValueContainerBool(&Config.KillonSQline), DT_BOOLEAN, NoValidation}, {"operserv", "notifications", "", new ValueContainerString(&OSNotifications), DT_STRING, NoValidation}, {"operserv", "limitsessions", "no", new ValueContainerBool(&Config.LimitSessions), DT_BOOLEAN, NoValidation}, @@ -772,9 +786,9 @@ int ServerConfig::Read(bool bail) {DT_CHARPTR}, InitModules, DoModule, DoneModules}, {"opertype", - {"name", "commands", "privs", NULL}, - {"", "", "", NULL}, - {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR}, + {"name", "inherits", "commands", "privs", NULL}, + {"", "", "", "", NULL}, + {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR}, InitOperTypes, DoOperType, DoneOperTypes}, {"oper", {"name", "type", NULL}, @@ -1619,8 +1633,8 @@ int read_config(int reload) } } - Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSGLine = Config.WallOSSQLine = - Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSGLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid = + Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSNLine = Config.WallOSSQLine = + Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSNLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid = Config.WallDrop = false; if (!OSNotifications.empty()) { spacesepstream notifications(OSNotifications); @@ -1633,13 +1647,13 @@ int read_config(int reload) else if (notice == "osclearmodes") Config.WallOSClearmodes = true; else if (notice == "oskick") Config.WallOSKick = true; else if (notice == "osakill") Config.WallOSAkill = true; - else if (notice == "ossgline") Config.WallOSSGLine = true; + else if (notice == "ossnline") Config.WallOSSNLine = true; else if (notice == "ossqline") Config.WallOSSQLine = true; else if (notice == "osszline") Config.WallOSSZLine = true; else if (notice == "osnoop") Config.WallOSNoOp = true; else if (notice == "osjupe") Config.WallOSJupe = true; else if (notice == "akillexpire") Config.WallAkillExpire = true; - else if (notice == "sglineexpire") Config.WallSGLineExpire = true; + else if (notice == "snlineexpire") Config.WallSNLineExpire = true; else if (notice == "sqlineexpire") Config.WallSQLineExpire = true; else if (notice == "szlineexpire") Config.WallSZLineExpire = true; else if (notice == "exceptionexpire") Config.WallExceptionExpire = true; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f8547872b..2af2b3ea9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,5 +1,4 @@ -# Find all the *.c and *.cpp files within the current source directory, and sort the list -file(GLOB CORE_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") +# Find all the *.cpp files within the current source directory, and sort the list file(GLOB CORE_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") set(CORE_SRCS ${CORE_SRCS_C} ${CORE_SRCS_CPP}) sort_list(CORE_SRCS) diff --git a/src/core/Makefile b/src/core/Makefile index 122522d69..e1dec257c 100644 --- a/src/core/Makefile +++ b/src/core/Makefile @@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'PROFILE=${PROFILE}' 'SHARED=${SHARED}' \ 'MODULEFLAGS=${MODULEFLAGS}' 'MAKEBIN=${MAKEBIN}' -OBJECTS= $(SRCS:.c=.so) -OBJECTS+= $(SRCS:.cpp=.so) +OBJECTS= $(SRCS:.cpp=.so) CDEFS= -rdynamic -Wall all: modules subs @@ -21,10 +20,7 @@ install: distclean: spotless -.SUFFIXES: .c .cpp .so - -.c.so: - $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $< +.SUFFIXES: .cpp .so .cpp.so: $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $< diff --git a/src/core/bs_act.c b/src/core/bs_act.cpp index d0b9c8b08..d313fd587 100644 --- a/src/core/bs_act.c +++ b/src/core/bs_act.cpp @@ -23,7 +23,7 @@ class CommandBSAct : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - ChannelInfo *ci = cs_findchan(params[0].c_str()); + ChannelInfo *ci = cs_findchan(params[0]); ci::string message = params[1]; if (!check_access(u, ci, CA_SAY)) @@ -65,6 +65,11 @@ class CommandBSAct : public Command notice_help(Config.s_BotServ, u, BOT_HELP_ACT); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ACT); + } }; class BSAct : public Module @@ -75,13 +80,7 @@ class BSAct : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSAct()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ACT); + this->AddCommand(BotServ, new CommandBSAct()); } }; diff --git a/src/core/bs_assign.c b/src/core/bs_assign.cpp index f37db9aca..d5fa0bdef 100644 --- a/src/core/bs_assign.c +++ b/src/core/bs_assign.cpp @@ -75,6 +75,11 @@ class CommandBSAssign : public Command { syntax_error(Config.s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ASSIGN); + } }; class BSAssign : public Module @@ -85,13 +90,7 @@ class BSAssign : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSAssign); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ASSIGN); + this->AddCommand(BotServ, new CommandBSAssign); } }; diff --git a/src/core/bs_badwords.c b/src/core/bs_badwords.cpp index af616c41a..7a9c6ebdf 100644 --- a/src/core/bs_badwords.c +++ b/src/core/bs_badwords.cpp @@ -14,40 +14,106 @@ #include "module.h" -int badwords_del_callback(User * u, int num, va_list args); -int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header); -int badwords_list_callback(User * u, int num, va_list args); +class BadwordsListCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + bool SentHeader; + public: + BadwordsListCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, false), u(_u), ci(_ci), SentHeader(false) + { + } + + ~BadwordsListCallback() + { + if (!SentHeader) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetBadWordCount()) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str()); + } + + DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1)); + } + + static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw) + { + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)" : ((bw->type == BW_END) ? "(END)" : "")))); + } +}; + +class BadwordsDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + unsigned Deleted; + public: + BadwordsDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0) + { + } + + ~BadwordsDelCallback() + { + if (!Deleted) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); + else if (Deleted == 1) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str()); + else + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str()); + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetBadWordCount()) + return; + + ++Deleted; + ci->EraseBadWord(Number - 1); + } +}; class CommandBSBadwords : public Command { private: CommandReturn DoList(User *u, ChannelInfo *ci, const ci::string &word) { - int sent_header = 0; - if (!ci->GetBadWordCount()) { notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str()); - return MOD_CONT; - } - if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length()) - { - process_numlist(word.c_str(), NULL, badwords_list_callback, u, ci, &sent_header); } + else if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length()) + (new BadwordsListCallback(u, ci, word.c_str()))->Process(); else { + bool SentHeader = false; + for (unsigned i = 0; i < ci->GetBadWordCount(); i++) { - BadWord *badword = ci->GetBadWord(i); + BadWord *bw = ci->GetBadWord(i); - if (!word.empty() && !Anope::Match(badword->word, word.c_str(), false)) + if (!word.empty() && !Anope::Match(bw->word, word.c_str(), false)) continue; - badwords_list(u, i, ci, &sent_header); + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str()); + } + + BadwordsListCallback::DoList(u, ci, i, bw); } + + if (!SentHeader) + notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); } - if (!sent_header) - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); return MOD_CONT; } @@ -83,7 +149,7 @@ class CommandBSBadwords : public Command { BadWord *bw = ci->GetBadWord(i); - if (!bw->word.empty() && (Config.BSCaseSensitive && !stricmp(bw->word.c_str(), realword.c_str()) + if (!bw->word.empty() && ((Config.BSCaseSensitive && !stricmp(bw->word.c_str(), realword.c_str())) || (!Config.BSCaseSensitive && bw->word == realword.c_str()))) { notice_lang(Config.s_BotServ, u, BOT_BADWORDS_ALREADY_EXISTS, bw->word.c_str(), ci->name.c_str()); @@ -102,33 +168,7 @@ class CommandBSBadwords : public Command { /* Special case: is it a number/list? Only do search if it isn't. */ if (!word.empty() && isdigit(word[0]) && strspn(word.c_str(), "1234567890,-") == word.length()) - { - int count, deleted, last = -1; - deleted = process_numlist(word.c_str(), &count, badwords_del_callback, u, ci, &last); - - if (!deleted) - { - if (count == 1) - { - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY, last, ci->name.c_str()); - } - else - { - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str()); - } - } - else if (deleted == 1) - { - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str()); - } - else - { - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, deleted, ci->name.c_str()); - } - - if (deleted) - ci->CleanBadWords(); - } + (new BadwordsDelCallback(u, ci, word.c_str()))->Process(); else { unsigned i; @@ -148,7 +188,7 @@ class CommandBSBadwords : public Command return MOD_CONT; } - ci->EraseBadWord(badword); + ci->EraseBadWord(i); notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str()); } @@ -219,6 +259,11 @@ class CommandBSBadwords : public Command { syntax_error(Config.s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BADWORDS); + } }; class BSBadwords : public Module @@ -229,58 +274,8 @@ class BSBadwords : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSBadwords); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BADWORDS); + this->AddCommand(BotServ, new CommandBSBadwords); } }; -int badwords_del_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *last = va_arg(args, int *); - - *last = num; - - if (num < 1 || num > ci->GetBadWordCount()) - return 0; - - ci->GetBadWord(num - 1)->InUse = false; - - return 1; -} - -int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header) -{ - BadWord *bw = ci->GetBadWord(index); - - if (!*sent_header) - { - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str()); - *sent_header = 1; - } - - notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, index + 1, bw->word.c_str(), - ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)" - : ((bw->type == BW_END) ? "(END)" : ""))) - ); - - return 1; -} - -int badwords_list_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - - if (num < 1 || num > ci->GetBadWordCount()) - return 0; - - return badwords_list(u, num - 1, ci, sent_header); -} - MODULE_INIT(BSBadwords) diff --git a/src/core/bs_bot.c b/src/core/bs_bot.cpp index 8abfecde8..1d3103e29 100644 --- a/src/core/bs_bot.c +++ b/src/core/bs_bot.cpp @@ -242,7 +242,8 @@ class CommandBSBot : public Command the old nick. */ if (ircd->sqline) { - ircdproto->SendSQLineDel(bi->nick); + XLine x(bi->nick.c_str()); + ircdproto->SendSQLineDel(&x); } /* We check whether user with this nick is online, and kill it if so */ @@ -251,9 +252,11 @@ class CommandBSBot : public Command if (user) ircdproto->SendQuit(bi, "Quit: Be right back"); - else { + else + { ircdproto->SendChangeBotNick(bi, nick); - ircdproto->SendSQLine(bi->nick, "Reserved for services"); + XLine x(bi->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); } if (bi->nick != nick) @@ -273,7 +276,8 @@ class CommandBSBot : public Command bi->uid = ts6_uid_retrieve(); } ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid); - ircdproto->SendSQLine(bi->nick, "Reserved for services"); + XLine x(bi->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); bi->RejoinAll(); } @@ -309,7 +313,8 @@ class CommandBSBot : public Command FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi)); ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str()); - ircdproto->SendSQLineDel(bi->nick); + XLine x(bi->nick.c_str()); + ircdproto->SendSQLineDel(&x); delete bi; notice_lang(Config.s_BotServ, u, BOT_BOT_DELETED, nick); @@ -404,6 +409,11 @@ class CommandBSBot : public Command { syntax_error(Config.s_BotServ, u, "BOT", BOT_BOT_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOT); + } }; class BSBot : public Module @@ -414,13 +424,7 @@ class BSBot : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSBot()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOT); + this->AddCommand(BotServ, new CommandBSBot()); } }; diff --git a/src/core/bs_botlist.c b/src/core/bs_botlist.cpp index 540cac30d..ebebf7a71 100644 --- a/src/core/bs_botlist.c +++ b/src/core/bs_botlist.cpp @@ -23,34 +23,39 @@ class CommandBSBotList : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - int i, count = 0; - BotInfo *bi; + unsigned count = 0; - if (!nbots) { + if (BotListByNick.empty()) + { notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY); return MOD_CONT; } - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - if (!(bi->HasFlag(BI_PRIVATE))) { - if (!count) - notice_lang(Config.s_BotServ, u, BOT_BOTLIST_HEADER); - count++; - u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str()); - } + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + BotInfo *bi = it->second; + + if (!bi->HasFlag(BI_PRIVATE)) + { + if (!count) + notice_lang(Config.s_BotServ, u, BOT_BOTLIST_HEADER); + count++; + u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str()); } } - if (u->Account()->HasCommand("botserv/botlist") && count < nbots) { + if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size()) + { notice_lang(Config.s_BotServ, u, BOT_BOTLIST_PRIVATE_HEADER); - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - if (bi->HasFlag(BI_PRIVATE)) { - u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str()); - count++; - } + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + BotInfo *bi = it->second; + + if (bi->HasFlag(BI_PRIVATE)) + { + u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str()); + count++; } } } @@ -59,6 +64,7 @@ class CommandBSBotList : public Command notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY); else notice_lang(Config.s_BotServ, u, BOT_BOTLIST_FOOTER, count); + return MOD_CONT; } @@ -67,6 +73,11 @@ class CommandBSBotList : public Command notice_help(Config.s_BotServ, u, BOT_HELP_BOTLIST); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOTLIST); + } }; class BSBotList : public Module @@ -77,13 +88,7 @@ class BSBotList : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSBotList()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOTLIST); + this->AddCommand(BotServ, new CommandBSBotList()); } }; diff --git a/src/core/bs_help.c b/src/core/bs_help.cpp index d28595986..80070c138 100644 --- a/src/core/bs_help.c +++ b/src/core/bs_help.cpp @@ -25,7 +25,7 @@ class CommandBSHelp : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - mod_help_cmd(Config.s_BotServ, u, BOTSERV, params[0].c_str()); + mod_help_cmd(findbot(Config.s_BotServ), u, params[0].c_str()); return MOD_CONT; } @@ -33,7 +33,8 @@ class CommandBSHelp : public Command { // Abuse syntax error to display general list help. notice_help(Config.s_BotServ, u, BOT_HELP); - FOREACH_MOD(I_OnBotServHelp, OnBotServHelp(u)); + for (CommandMap::const_iterator it = BotServ->Commands.begin(); it != BotServ->Commands.end(); ++it) + it->second->OnServHelp(u); notice_help(Config.s_BotServ, u, BOT_HELP_FOOTER, Config.BSMinUsers); } }; @@ -46,7 +47,7 @@ class BSHelp : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSHelp()); + this->AddCommand(BotServ, new CommandBSHelp()); } }; diff --git a/src/core/bs_info.c b/src/core/bs_info.cpp index 3ac3e9540..4e8cf042f 100644 --- a/src/core/bs_info.c +++ b/src/core/bs_info.cpp @@ -19,25 +19,24 @@ class CommandBSInfo : public Command private: void send_bot_channels(User * u, BotInfo * bi) { - int i; - ChannelInfo *ci; char buf[307], *end; *buf = 0; end = buf; - for (i = 0; i < 256; i++) { - for (ci = chanlists[i]; ci; ci = ci->next) { - if (ci->bi == bi) { - if (strlen(buf) + strlen(ci->name.c_str()) > 300) { - u->SendMessage(Config.s_BotServ, "%s", buf); - *buf = 0; - end = buf; - } - end += - snprintf(end, sizeof(buf) - (end - buf), " %s ", - ci->name.c_str()); + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; + + if (ci->bi == bi) + { + if (strlen(buf) + strlen(ci->name.c_str()) > 300) + { + u->SendMessage(Config.s_BotServ, "%s", buf); + *buf = 0; + end = buf; } + end += snprintf(end, sizeof(buf) - (end - buf), " %s ", ci->name.c_str()); } } @@ -79,7 +78,7 @@ class CommandBSInfo : public Command } else if ((ci = cs_findchan(query))) { - if (!IsFounder(u, ci) && !u->Account()->HasPriv("botserv/administration")) + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration")) { notice_lang(Config.s_BotServ, u, ACCESS_DENIED); return MOD_CONT; @@ -241,6 +240,11 @@ class CommandBSInfo : public Command { syntax_error(Config.s_BotServ, u, "INFO", BOT_INFO_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_INFO); + } }; class BSInfo : public Module @@ -251,13 +255,7 @@ class BSInfo : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSInfo()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_INFO); + this->AddCommand(BotServ, new CommandBSInfo()); } }; diff --git a/src/core/bs_kick.c b/src/core/bs_kick.cpp index 766239c73..6c8e020e4 100644 --- a/src/core/bs_kick.c +++ b/src/core/bs_kick.cpp @@ -325,6 +325,11 @@ class CommandBSKick : public Command { syntax_error(Config.s_BotServ, u, "KICK", BOT_KICK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_KICK); + } }; class BSKick : public Module @@ -335,13 +340,7 @@ class BSKick : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSKick()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_KICK); + this->AddCommand(BotServ, new CommandBSKick()); } }; diff --git a/src/core/bs_say.c b/src/core/bs_say.cpp index 9cd630eb8..a388a1ec9 100644 --- a/src/core/bs_say.c +++ b/src/core/bs_say.cpp @@ -71,6 +71,11 @@ class CommandBSSay : public Command { syntax_error(Config.s_BotServ, u, "SAY", BOT_SAY_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SAY); + } }; class BSSay : public Module @@ -81,13 +86,7 @@ class BSSay : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSSay()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SAY); + this->AddCommand(BotServ, new CommandBSSay()); } }; diff --git a/src/core/bs_set.c b/src/core/bs_set.cpp index 0614651cc..a5fee9d4f 100644 --- a/src/core/bs_set.c +++ b/src/core/bs_set.cpp @@ -176,6 +176,11 @@ class CommandBSSet : public Command { syntax_error(Config.s_BotServ, u, "SET", BOT_SET_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SET); + } }; class BSSet : public Module { @@ -185,13 +190,7 @@ class BSSet : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSSet()); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SET); + this->AddCommand(BotServ, new CommandBSSet()); } }; diff --git a/src/core/bs_unassign.c b/src/core/bs_unassign.cpp index e053f75d7..72e62a310 100644 --- a/src/core/bs_unassign.c +++ b/src/core/bs_unassign.cpp @@ -53,6 +53,11 @@ class CommandBSUnassign : public Command { syntax_error(Config.s_BotServ, u, "UNASSIGN", BOT_UNASSIGN_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_UNASSIGN); + } }; class BSUnassign : public Module @@ -63,13 +68,7 @@ class BSUnassign : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(BOTSERV, new CommandBSUnassign); - - ModuleManager::Attach(I_OnBotServHelp, this); - } - void OnBotServHelp(User *u) - { - notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_UNASSIGN); + this->AddCommand(BotServ, new CommandBSUnassign); } }; diff --git a/src/core/cs_access.c b/src/core/cs_access.c deleted file mode 100644 index e4e1d0e4b..000000000 --- a/src/core/cs_access.c +++ /dev/null @@ -1,589 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -static int access_del(User * u, ChannelInfo *ci, ChanAccess * access, int *perm, int uacc) -{ - if (!access->in_use) - return 0; - if (uacc <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) - { - (*perm)++; - return 0; - } - NickCore *nc = access->nc; - access->nc = NULL; - access->in_use = 0; - - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, nc)); - - return 1; -} - -static int access_del_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *last = va_arg(args, int *); - int *perm = va_arg(args, int *); - int uacc = va_arg(args, int); - if (num < 1 || num > ci->GetAccessCount()) - return 0; - *last = num; - return access_del(u, ci, ci->GetAccess(num - 1), perm, uacc); -} - - -static int access_list(User * u, int index, ChannelInfo * ci, int *sent_header) -{ - ChanAccess *access = ci->GetAccess(index); - const char *xop; - - if (!access->in_use) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); - *sent_header = 1; - } - - if (ci->HasFlag(CI_XOP)) - { - xop = get_xop_level(access->level); - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1, xop, access->nc->display); - } - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, index + 1, access->level, access->nc->display); - return 1; -} - -static int access_list_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - if (num < 1 || num > ci->GetAccessCount()) - return 0; - return access_list(u, num - 1, ci, sent_header); -} - -static int access_view(User *u, int index, ChannelInfo *ci, int *sent_header) -{ - ChanAccess *access = ci->GetAccess(index); - const char *xop; - char timebuf[64]; - tm tm; - - if (!access || !access->in_use) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); - *sent_header = 1; - } - - memset(&timebuf, 0, sizeof(timebuf)); - if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account())) - sprintf(timebuf, "Now"); - else if (access->last_seen == 0) - sprintf(timebuf, "Never"); - else - { - tm = *localtime(&access->last_seen); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); - } - - if (ci->HasFlag(CI_XOP)) - { - xop = get_xop_level(access->level); - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, index + 1, xop, access->nc->display, access->creator.c_str(), timebuf); - } - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, index + 1, access->level, access->nc->display, access->creator.c_str(), timebuf); - - return 1; -} - -static int access_view_callback(User *u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - if (num < 1 || num > ci->GetAccessCount()) - return 0; - return access_view(u, num - 1, ci, sent_header); -} - -class CommandCSAccess : public Command -{ - public: - CommandCSAccess() : Command("ACCESS", 2, 4) - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - const char *chan = params[0].c_str(); - ci::string cmd = params[1]; - const char *nick = params.size() > 2 ? params[2].c_str() : NULL; - const char *s = params.size() > 3 ? params[3].c_str() : NULL; - - ChannelInfo *ci = cs_findchan(chan); - NickAlias *na = NULL; - NickCore *nc; - ChanAccess *access; - - unsigned i; - int level = 0, ulev; - bool is_list = cmd == "LIST" || cmd == "VIEW"; - - /* If LIST, we don't *require* any parameters, but we can take any. - * If DEL, we require a nick and no level. - * Else (ADD), we require a level (which implies a nick). */ - if (is_list || cmd == "CLEAR" ? 0 : (cmd == "DEL" ? (!nick || s) : !s)) - this->OnSyntaxError(u, cmd); - /* We still allow LIST in xOP mode, but not others */ - else if ((ci->HasFlag(CI_XOP)) && !is_list) - { - if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP_HOP, Config.s_ChanServ); - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP, Config.s_ChanServ); - } - else if (( - (is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list")) - || - (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify")) - )) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (cmd == "ADD") - { - if (readonly) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED); - return MOD_CONT; - } - - level = atoi(s); - ulev = get_access(u, ci); - - if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return MOD_CONT; - } - - if (!level) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO); - return MOD_CONT; - } - else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1); - return MOD_CONT; - } - - na = findnick(nick); - if (!na) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY); - return MOD_CONT; - } - else if (na->HasFlag(NS_FORBIDDEN)) - { - notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, nick); - return MOD_CONT; - } - - nc = na->nc; - access = ci->GetAccess(nc); - if (access) - { - /* Don't allow lowering from a level >= ulev */ - if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return MOD_CONT; - } - if (access->level == level) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display, chan, level); - return MOD_CONT; - } - access->level = level; - - FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na, level)); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " - << access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, nc->display, chan, level); - return MOD_CONT; - } - - if (ci->GetAccessCount() >= Config.CSAccessMax) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT, Config.CSAccessMax); - return MOD_CONT; - } - - std::string usernick = u->nick; - ci->AddAccess(nc, level, usernick); - - FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, na, level)); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " - << level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display, ci->name.c_str(), level); - } - else if (cmd == "DEL") - { - int deleted; - if (readonly) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED); - return MOD_CONT; - } - - if (!ci->GetAccessCount()) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan); - return MOD_CONT; - } - - /* Special case: is it a number/list? Only do search if it isn't. */ - if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick)) - { - int count, last = -1, perm = 0; - deleted = process_numlist(nick, &count, access_del_callback, u, ci, &last, &perm, get_access(u, ci)); - if (!deleted) - { - if (perm) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (count == 1) - { - last = atoi(nick); - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_SUCH_ENTRY, last, ci->name.c_str()); - } - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); - } - else - { - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) - << ") deleted access of user" << (deleted == 1 ? " " : "s ") << nick << " on " << chan; - if (deleted == 1) - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str()); - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, deleted, ci->name.c_str()); - } - } - else - { - na = findnick(nick); - if (!na) - { - notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, nick); - return MOD_CONT; - } - nc = na->nc; - access = ci->GetAccess(nc); - if (!access) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick, chan); - return MOD_CONT; - } - if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) - { - deleted = 0; - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - } - else - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display, ci->name.c_str()); - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) - << ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << chan; - access->nc = NULL; - access->in_use = 0; - deleted = 1; - } - } - - if (deleted) - { - /* We'll free the access entries no longer in use... */ - ci->CleanAccess(); - - /* Only call this event if na exists (if they deleted by user, not numlist). - * The callback for deleting by numlist will call this event otherwise - Adam */ - if (na) - { - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); - } - } - } - else if (cmd == "LIST") - { - int sent_header = 0; - - if (!ci->GetAccessCount()) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan); - return MOD_CONT; - } - if (nick && strspn(nick, "1234567890,-") == strlen(nick)) - process_numlist(nick, NULL, access_list_callback, u, ci, &sent_header); - else - { - for (i = 0; i < ci->GetAccessCount(); i++) - { - access = ci->GetAccess(i); - if (nick && access->nc && !Anope::Match(access->nc->display, nick, false)) - continue; - access_list(u, i, ci, &sent_header); - } - } - if (!sent_header) - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan); - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str()); - } - else if (cmd == "VIEW") - { - int sent_header = 0; - - if (!ci->GetAccessCount()) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan); - return MOD_CONT; - } - if (nick && strspn(nick, "1234567890,-") == strlen(nick)) - process_numlist(nick, NULL, access_view_callback, u, ci, &sent_header); - else - { - for (i = 0; i < ci->GetAccessCount(); ++i) - { - access = ci->GetAccess(i); - if (nick && access->nc && !Anope::Match(access->nc->display, nick, false)) - continue; - access_view(u, i, ci, &sent_header); - } - } - if (!sent_header) - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan); - else - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str()); - } - else if (cmd == "CLEAR") - { - if (readonly) - { - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED); - return MOD_CONT; - } - - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return MOD_CONT; - } - - ci->ClearAccess(); - - FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u)); - - notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name.c_str()); - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << " cleared access list on " << chan; - } - else - this->OnSyntaxError(u, ""); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS); - notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS_LEVELS); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX); - } -}; - - -class CommandCSLevels : public Command -{ - public: - CommandCSLevels() : Command("LEVELS", 2, 4) - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - const char *chan = params[0].c_str(); - ci::string cmd = params[1]; - const char *what = params.size() > 2 ? params[2].c_str() : NULL; - const char *s = params.size() > 3 ? params[3].c_str() : NULL; - char *error; - - ChannelInfo *ci = cs_findchan(chan); - int level; - int i; - - /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only - * one; else, we want none. - */ - if (cmd == "SET" ? !s : (cmd.substr(0, 3) == "DIS" ? (!what || s) : !!what)) - this->OnSyntaxError(u, cmd); - else if (ci->HasFlag(CI_XOP)) - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP); - else if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (cmd == "SET") { - level = strtol(s, &error, 10); - - if (!stricmp(s, "FOUNDER")) - { - level = ACCESS_FOUNDER; - *error = '\0'; - } - - if (*error != '\0') { - this->OnSyntaxError(u, "SET"); - return MOD_CONT; - } - - if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER) { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RANGE, - ACCESS_INVALID + 1, ACCESS_FOUNDER - 1); - return MOD_CONT; - } - - for (i = 0; levelinfo[i].what >= 0; i++) { - if (stricmp(levelinfo[i].name, what) == 0) { - ci->levels[levelinfo[i].what] = level; - FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level)); - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set level " << levelinfo[i].name - << " on channel " << ci->name << " to " << level; - if (level == ACCESS_FOUNDER) - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name, ci->name.c_str()); - else - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED, - levelinfo[i].name, ci->name.c_str(), level); - return MOD_CONT; - } - } - - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ); - - } else if (cmd == "DIS" || cmd == "DISABLE") { - for (i = 0; levelinfo[i].what >= 0; i++) { - if (stricmp(levelinfo[i].name, what) == 0) { - ci->levels[levelinfo[i].what] = ACCESS_INVALID; - FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what)); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name - << " on channel " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED, - levelinfo[i].name, chan); - return MOD_CONT; - } - } - - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ); - } else if (cmd == "LIST") { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_HEADER, chan); - - if (!levelinfo_maxwidth) { - for (i = 0; levelinfo[i].what >= 0; i++) { - int len = strlen(levelinfo[i].name); - if (len > levelinfo_maxwidth) - levelinfo_maxwidth = len; - } - } - - for (i = 0; levelinfo[i].what >= 0; i++) { - int j = ci->levels[levelinfo[i].what]; - - if (j == ACCESS_INVALID) { - j = levelinfo[i].what; - - if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE - || j == CA_NOJOIN) { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, - levelinfo_maxwidth, levelinfo[i].name); - } else { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, - levelinfo_maxwidth, levelinfo[i].name); - } - } else if (j == ACCESS_FOUNDER) { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_FOUNDER, - levelinfo_maxwidth, levelinfo[i].name); - } else { - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_NORMAL, - levelinfo_maxwidth, levelinfo[i].name, j); - } - } - - } else if (cmd == "RESET") { - reset_levels(ci); - FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0)); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " reset levels definitions on channel " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RESET, chan); - } else { - this->OnSyntaxError(u, ""); - } - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_ChanServ, u, CHAN_HELP_LEVELS); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX); - } -}; - - -class CSAccess : public Module -{ - public: - CSAccess(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(CHANSERV, new CommandCSAccess()); - this->AddCommand(CHANSERV, new CommandCSLevels()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_ACCESS); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LEVELS); - } -}; - - -MODULE_INIT(CSAccess) diff --git a/src/core/cs_access.cpp b/src/core/cs_access.cpp new file mode 100644 index 000000000..49d253d12 --- /dev/null +++ b/src/core/cs_access.cpp @@ -0,0 +1,664 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class AccessListCallback : public NumberList +{ + protected: + User *u; + ChannelInfo *ci; + bool SentHeader; + public: + AccessListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false) + { + } + + ~AccessListCallback() + { + if (SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); + } + + virtual void HandleNumber(unsigned Number) + { + if (Number > ci->GetAccessCount()) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); + } + + DoList(u, ci, Number - 1, ci->GetAccess(Number - 1)); + } + + static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access) + { + if (ci->HasFlag(CI_XOP)) + { + const char *xop = get_xop_level(access->level); + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop, access->nc->display); + } + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display); + } +}; + +class AccessViewCallback : public AccessListCallback +{ + public: + AccessViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AccessListCallback(_u, _ci, numlist) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAccessCount()) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); + } + + DoList(u, ci, Number - 1, ci->GetAccess(Number - 1)); + } + + static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access) + { + char timebuf[64]; + struct tm tm; + + memset(&timebuf, 0, sizeof(timebuf)); + if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account())) + snprintf(timebuf, sizeof(timebuf), "Now"); + else if (access->last_seen == 0) + snprintf(timebuf, sizeof(timebuf), "Never"); + else + { + tm = *localtime(&access->last_seen); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); + } + + if (ci->HasFlag(CI_XOP)) + { + const char *xop = get_xop_level(access->level); + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop, access->nc->display, access->creator.c_str(), timebuf); + } + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display, access->creator.c_str(), timebuf); + } +}; + +class AccessDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + unsigned Deleted; + std::string Nicks; + bool Denied; + public: + AccessDelCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), Deleted(0), Denied(false) + { + } + + ~AccessDelCallback() + { + if (Denied && !Deleted) + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + else if (!Deleted) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); + else + { + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user" << (Deleted == 1 ? " " : "s ") << Nicks << " on " << ci->name; + + if (Deleted == 1) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, Deleted, ci->name.c_str()); + } + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAccessCount()) + return; + + ChanAccess *access = ci->GetAccess(Number - 1); + + if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + { + Denied = true; + return; + } + + ++Deleted; + if (!Nicks.empty()) + Nicks += ", " + std::string(access->nc->display); + else + Nicks = access->nc->display; + + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc)); + + ci->EraseAccess(Number - 1); + } +}; + +class CommandCSAccess : public Command +{ + CommandReturn DoAdd(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string nick = params[2]; + int level = atoi(params[3].c_str()); + int ulev = get_access(u, ci); + + if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (!level) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO); + return MOD_CONT; + } + else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1); + return MOD_CONT; + } + + NickAlias *na = findnick(nick.c_str()); + if (!na) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY); + return MOD_CONT; + } + else if (na->HasFlag(NS_FORBIDDEN)) + { + notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, nick.c_str()); + return MOD_CONT; + } + + NickCore *nc = na->nc; + ChanAccess *access = ci->GetAccess(nc); + if (access) + { + /* Don't allow lowering from a level >= ulev */ + if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + if (access->level == level) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display, ci->name.c_str(), level); + return MOD_CONT; + } + access->level = level; + + FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level)); + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, nc->display, ci->name.c_str(), level); + return MOD_CONT; + } + + if (ci->GetAccessCount() >= Config.CSAccessMax) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT, Config.CSAccessMax); + return MOD_CONT; + } + + ci->AddAccess(nc, level, u->nick); + + FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level)); + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << level << " to " << na->nick << " (group " << nc->display << ") on channel " << +ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display, ci->name.c_str(), level); + + return MOD_CONT; + } + + CommandReturn DoDel(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string nick = params[2]; + + if (!ci->GetAccessCount()) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str()); + else if (isdigit(*nick.c_str()) && strspn(nick.c_str(), "1234567890,-") == nick.length()) + (new AccessDelCallback(u, ci, nick.c_str()))->Process(); + else + { + NickAlias *na = findnick(nick); + if (!na) + { + notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, nick.c_str()); + return MOD_CONT; + } + + NickCore *nc = na->nc; + + unsigned i; + ChanAccess *access = NULL; + for (i = 0; i < ci->GetAccessCount(); ++i) + { + access = ci->GetAccess(i); + + if (access->nc == nc) + break; + } + + if (i == ci->GetAccessCount()) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str()); + } + else if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + } + else + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display, ci->name.c_str()); + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << ci->name; + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); + + ci->EraseAccess(i); + } + } + + return MOD_CONT; + } + + CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string nick = params.size() > 2 ? params[2] : ""; + + if (!ci->GetAccessCount()) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str()); + else if (!nick.empty() && strspn(nick.c_str(), "1234567890,-") == nick.length()) + (new AccessListCallback(u, ci, nick.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < ci->GetAccessCount(); i++) + { + ChanAccess *access = ci->GetAccess(i); + + if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick)) + continue; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); + } + + AccessListCallback::DoList(u, ci, i, access); + } + + if (SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); + } + + return MOD_CONT; + } + + CommandReturn DoView(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string nick = params.size() > 2 ? params[2] : ""; + + if (!ci->GetAccessCount()) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str()); + else if (!nick.empty() && strspn(nick.c_str(), "1234567890,-") == nick.length()) + (new AccessViewCallback(u, ci, nick.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < ci->GetAccessCount(); ++i) + { + ChanAccess *access = ci->GetAccess(i); + + if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick)) + continue; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str()); + } + + AccessViewCallback::DoList(u, ci, i, access); + } + + if (SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str()); + } + + return MOD_CONT; + } + + CommandReturn DoClear(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + } + else + { + ci->ClearAccess(); + + FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u)); + + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name.c_str()); + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << " cleared access list on " << ci->name; + } + + return MOD_CONT; + } + + public: + CommandCSAccess() : Command("ACCESS", 2, 4) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + const char *chan = params[0].c_str(); + ci::string cmd = params[1]; + const char *nick = params.size() > 2 ? params[2].c_str() : NULL; + const char *s = params.size() > 3 ? params[3].c_str() : NULL; + + ChannelInfo *ci = cs_findchan(chan); + + bool is_list = cmd == "LIST" || cmd == "VIEW"; + + /* If LIST, we don't *require* any parameters, but we can take any. + * If DEL, we require a nick and no level. + * Else (ADD), we require a level (which implies a nick). */ + if (is_list || cmd == "CLEAR" ? 0 : (cmd == "DEL" ? (!nick || s) : !s)) + this->OnSyntaxError(u, cmd); + /* We still allow LIST in xOP mode, but not others */ + else if ((ci->HasFlag(CI_XOP)) && !is_list) + { + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP_HOP, Config.s_ChanServ); + else + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP, Config.s_ChanServ); + } + else if (( + (is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list")) + || + (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify")) + )) + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + else if (readonly && (cmd == "ADD" || cmd == "DEL" || cmd == "CLEAR")) + { + notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED); + } + else if (cmd == "ADD") + { + this->DoAdd(u, ci, params); + } + else if (cmd == "DEL") + { + this->DoDel(u, ci, params); + } + else if (cmd == "LIST") + { + this->DoList(u, ci, params); + } + else if (cmd == "VIEW") + { + this->DoView(u, ci, params); + } + else if (cmd == "CLEAR") + { + this->DoClear(u, ci, params); + } + else + { + this->OnSyntaxError(u, ""); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS); + notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS_LEVELS); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX); + } +}; + + +class CommandCSLevels : public Command +{ + CommandReturn DoSet(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string what = params[2]; + const ci::string lev = params[3]; + + char *error; + int level = strtol(lev.c_str(), &error, 10); + + if (lev == "FONDER") + { + level = ACCESS_FOUNDER; + *error = '\0'; + } + + if (*error != '\0') + { + this->OnSyntaxError(u, "SET"); + } + else if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER) + { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1); + } + else + { + for (int i = 0; levelinfo[i].what >= 0; i++) + { + if (levelinfo[i].name == what) + { + ci->levels[levelinfo[i].what] = level; + FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level)); + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set level " << levelinfo[i].name << " on channel " << ci->name << " to " << level; + if (level == ACCESS_FOUNDER) + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED, levelinfo[i].name, ci->name.c_str(), level); + return MOD_CONT; + } + } + } + + + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what.c_str(), Config.s_ChanServ); + + return MOD_CONT; + } + + CommandReturn DoDisable(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + const ci::string what = params[2]; + + /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */ + if (what != "FOUNDER") + { + for (int i = 0; levelinfo[i].what >= 0; i++) + { + if (levelinfo[i].name == what) + { + ci->levels[levelinfo[i].what] = ACCESS_INVALID; + FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what)); + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name << " on channel " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED, levelinfo[i].name, ci->name.c_str()); + return MOD_CONT; + } + } + } + + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what.c_str(), Config.s_ChanServ); + + return MOD_CONT; + } + + CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_HEADER, ci->name.c_str()); + + if (!levelinfo_maxwidth) + { + for (int i = 0; levelinfo[i].what >= 0; i++) { + int len = strlen(levelinfo[i].name); + if (len > levelinfo_maxwidth) + levelinfo_maxwidth = len; + } + } + + for (int i = 0; levelinfo[i].what >= 0; i++) { + int j = ci->levels[levelinfo[i].what]; + + if (j == ACCESS_INVALID) { + j = levelinfo[i].what; + + if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE + || j == CA_NOJOIN) { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name); + } else { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name); + } + } else if (j == ACCESS_FOUNDER) { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_FOUNDER, levelinfo_maxwidth, levelinfo[i].name); + } else { + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_NORMAL, levelinfo_maxwidth, levelinfo[i].name, j); + } + } + + return MOD_CONT; + } + + CommandReturn DoReset(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) + { + reset_levels(ci); + FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0)); + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " reset levels definitions on channel " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RESET, ci->name.c_str()); + return MOD_CONT; + } + + public: + CommandCSLevels() : Command("LEVELS", 2, 4) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + const char *chan = params[0].c_str(); + ci::string cmd = params[1]; + const char *what = params.size() > 2 ? params[2].c_str() : NULL; + const char *s = params.size() > 3 ? params[3].c_str() : NULL; + + ChannelInfo *ci = cs_findchan(chan); + + /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only + * one; else, we want none. + */ + if (cmd == "SET" ? !s : (cmd.substr(0, 3) == "DIS" ? (!what || s) : !!what)) + this->OnSyntaxError(u, cmd); + else if (ci->HasFlag(CI_XOP)) + notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP); + else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + else if (cmd == "SET") + { + this->DoSet(u, ci, params); + } + else if (cmd == "DIS" || cmd == "DISABLE") + { + this->DoDisable(u, ci, params); + } + else if (cmd == "LIST") + { + this->DoList(u, ci, params); + } + else if (cmd == "RESET") + { + this->DoReset(u, ci, params); + } + else + { + this->OnSyntaxError(u, ""); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_LEVELS); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_ACCESS); + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LEVELS); + } +}; + + +class CSAccess : public Module +{ + public: + CSAccess(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + this->AddCommand(ChanServ, new CommandCSAccess()); + this->AddCommand(ChanServ, new CommandCSLevels()); + } +}; + + +MODULE_INIT(CSAccess) diff --git a/src/core/cs_akick.c b/src/core/cs_akick.cpp index ac17ef504..e2ad9de99 100644 --- a/src/core/cs_akick.c +++ b/src/core/cs_akick.cpp @@ -45,103 +45,125 @@ static void split_usermask(const char *mask, const char **nick, const char **use delete [] mask2; } -int akick_del_callback(User * u, int num, va_list args) +class AkickListCallback : public NumberList { - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *last = va_arg(args, int *); + protected: + User *u; + ChannelInfo *ci; + bool SentHeader; + public: + AkickListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false) + { + } - *last = num; + ~AkickListCallback() + { + if (!SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); + } - if (num < 1 || num > ci->GetAkickCount()) - return 0; + virtual void HandleNumber(unsigned Number) + { + if (Number > ci->GetAkickCount()) + return; - ci->GetAkick(num - 1)->InUse = false; - return 1; -} + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); + } + DoList(u, ci, Number - 1, ci->GetAkick(Number - 1)); + } -int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header) -{ - AutoKick *akick = ci->GetAkick(index); + static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick) + { + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1, + ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()), + (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON))); + } +}; - if (!akick->InUse) - return 0; - if (!*sent_header) { - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); - *sent_header = 1; +class AkickViewCallback : public AkickListCallback +{ + public: + AkickViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AkickListCallback(u, ci, numlist) + { } - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1, - ((akick->HasFlag(AK_ISNICK)) ? akick->nc-> - display : akick->mask.c_str()), - (!akick->reason.empty() ? akick-> - reason.c_str() : getstring(u, NO_REASON))); - return 1; -} + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAkickCount()) + return; -int akick_list_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - if (num < 1 || num > ci->GetAkickCount()) - return 0; - return akick_list(u, num - 1, ci, sent_header); -} + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); + } -int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header) -{ - AutoKick *akick = ci->GetAkick(index); - char timebuf[64]; - struct tm tm; - - if (!akick->InUse) - return 0; - if (!*sent_header) { - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); - *sent_header = 1; + DoList(u, ci, Number - 1, ci->GetAkick(Number - 1)); } - if (akick->addtime) { - tm = *localtime(&akick->addtime); - strftime_lang(timebuf, sizeof(timebuf), u, - STRFTIME_SHORT_DATE_FORMAT, &tm); - } else { - snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN)); + static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick) + { + char timebuf[64]; + struct tm tm; + + memset(&timebuf, 0, sizeof(timebuf)); + + if (akick->addtime) + { + tm = *localtime(&akick->addtime); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + } + else + snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN)); + + notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1, + ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()), + !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf, + (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON))); + + if (akick->last_used) + { + char last_used[64]; + tm = *localtime(&akick->last_used); + strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used); + } } +}; - notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1, - ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()), - !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf, - (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON))); - if (akick->last_used) +class AkickDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + unsigned Deleted; + public: + AkickDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0) { - char last_used[64]; - tm = *localtime(&akick->last_used); - strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used); } - return 1; -} -int akick_view_callback(User * u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - if (num < 1 || num > ci->GetAkickCount()) - return 0; - return akick_view(u, num - 1, ci, sent_header); -} + ~AkickDelCallback() + { + if (!Deleted) + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); + else if (Deleted == 1) + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, Deleted, ci->name.c_str()); + } -int get_access_nc(NickCore *nc, ChannelInfo *ci) -{ - ChanAccess *access; - if (!ci || !nc) - return 0; + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAkickCount()) + return; - if ((access = ci->GetAccess(nc))) - return access->level; - return 0; -} + ++Deleted; + ci->EraseAkick(Number - 1); + } +}; class CommandCSAKick : public Command { @@ -149,10 +171,9 @@ class CommandCSAKick : public Command { ci::string mask = params[2]; ci::string reason = params.size() > 3 ? params[3] : ""; - NickAlias *na = findnick(mask.c_str()); + NickAlias *na = findnick(mask); NickCore *nc = NULL; AutoKick *akick; - int i; if (!na) { @@ -189,7 +210,7 @@ class CommandCSAKick : public Command * or whether the mask matches a user with higher/equal access - Viper */ if ((ci->HasFlag(CI_PEACE)) && nc) { - if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci))) + if ((nc == ci->founder) || (get_access_level(ci, nc) >= get_access(u, ci))) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return; @@ -197,42 +218,40 @@ class CommandCSAKick : public Command } else if ((ci->HasFlag(CI_PEACE))) { - char buf[BUFSIZE]; /* Match against all currently online users with equal or * higher access. - Viper */ - for (i = 0; i < 1024; i++) + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) { - for (User *u2 = userlist[i]; u2; u2 = u2->next) + User *u2 = it->second; + + if (check_access(u2, ci, CA_FOUNDER) || (get_access(u2, ci) >= get_access(u, ci))) { - if (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) + if (match_usermask(mask.c_str(), u2)) { - if (match_usermask(mask.c_str(), u2)) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return; - } + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return; } } - } - + } - /* Match against the lastusermask of all nickalias's with equal - * or higher access. - Viper */ - for (i = 0; i < 1024; i++) + /* Match against the lastusermask of all nickalias's with equal + * or higher access. - Viper */ + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (NickAlias *na2 = nalists[i]; na2; na2 = na2->next) + NickAlias *na2 = it->second; + + if (na2->HasFlag(NS_FORBIDDEN)) + continue; + + if (na2->nc && ((na2->nc == ci->founder) || (get_access_level(ci, na2->nc) >= get_access(u, ci)))) { - if (na2->HasFlag(NS_FORBIDDEN)) - continue; + char buf[BUFSIZE]; - if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci) >= get_access(u, ci)))) + snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask); + if (Anope::Match(buf, mask.c_str(), false)) { - snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask); - if (Anope::Match(buf, mask.c_str(), false)) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return; - } + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return; } } } @@ -241,8 +260,6 @@ class CommandCSAKick : public Command for (unsigned j = 0; j < ci->GetAkickCount(); ++j) { akick = ci->GetAkick(j); - if (!akick->InUse) - continue; if ((akick->HasFlag(AK_ISNICK)) ? akick->nc == nc : akick->mask == mask) { notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS, (akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str(), ci->name.c_str()); @@ -262,6 +279,8 @@ class CommandCSAKick : public Command else akick = ci->AddAkick(u->nick, mask.c_str(), !reason.empty() ? reason.c_str() : ""); + FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick)); + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str()); this->DoEnforce(u, ci, params); @@ -281,14 +300,14 @@ class CommandCSAKick : public Command return; } - na = findnick(mask.c_str()); + na = findnick(mask); nc = (na ? na->nc : NULL); for (i = 0; i < ci->GetAkickCount(); ++i) { akick = ci->GetAkick(i); - if (!akick->InUse || akick->HasFlag(AK_ISNICK)) + if (akick->HasFlag(AK_ISNICK)) continue; if (akick->mask == mask) break; @@ -321,14 +340,14 @@ class CommandCSAKick : public Command return; } - na = findnick(mask.c_str()); + na = findnick(mask); nc = (na ? na->nc : NULL); for (i = 0; i < ci->GetAkickCount(); ++i) { akick = ci->GetAkick(i); - if (!akick->InUse || akick->HasFlag(AK_ISNICK)) + if (akick->HasFlag(AK_ISNICK)) continue; if (akick->mask == mask) break; @@ -357,37 +376,17 @@ class CommandCSAKick : public Command } /* Special case: is it a number/list? Only do search if it isn't. */ - if (isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str())) - { - int last = -1, deleted, count; - - deleted = process_numlist(mask.c_str(), &count, akick_del_callback, u, ci, &last); - - if (!deleted) - { - if (count == 1) - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name.c_str()); - else - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); - } - else if (deleted == 1) - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str()); - else - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name.c_str()); - if (deleted) - ci->CleanAkick(); - } + if (isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkickDelCallback(u, ci, mask.c_str()))->Process(); else { - NickAlias *na = findnick(mask.c_str()); + NickAlias *na = findnick(mask); NickCore *nc = (na ? na->nc : NULL); for (i = 0; i < ci->GetAkickCount(); ++i) { akick = ci->GetAkick(i); - if (!akick->InUse) - continue; if (((akick->HasFlag(AK_ISNICK)) && akick->nc == nc) || (!(akick->HasFlag(AK_ISNICK)) && akick->mask == mask)) @@ -400,7 +399,7 @@ class CommandCSAKick : public Command return; } - ci->EraseAkick(akick); + ci->EraseAkick(i); notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str()); } @@ -408,10 +407,7 @@ class CommandCSAKick : public Command void DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) { - int sent_header = 0; ci::string mask = params.size() > 2 ? params[2] : ""; - unsigned i; - AutoKick *akick; if (!ci->GetAkickCount()) { @@ -419,16 +415,16 @@ class CommandCSAKick : public Command return; } - if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str())) - process_numlist(mask.c_str(), NULL, akick_list_callback, u, ci, &sent_header); + if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkickListCallback(u, ci, mask.c_str()))->Process(); else { - for (i = 0; i < ci->GetAkickCount(); ++i) + bool SentHeader = false; + + for (unsigned i = 0; i < ci->GetAkickCount(); ++i) { - akick = ci->GetAkick(i); + AutoKick *akick = ci->GetAkick(i); - if (!akick->InUse) - continue; if (!mask.empty()) { if (!(akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false)) @@ -436,21 +432,24 @@ class CommandCSAKick : public Command if ((akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->nc->display, mask.c_str(), false)) continue; } - akick_list(u, i, ci, &sent_header); + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); + } + + AkickListCallback::DoList(u, ci, i, akick); } + + if (!SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); } - - if (!sent_header) - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); - } void DoView(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) { - int sent_header = 0; ci::string mask = params.size() > 2 ? params[2] : ""; - AutoKick *akick; - unsigned i; if (!ci->GetAkickCount()) { @@ -458,16 +457,16 @@ class CommandCSAKick : public Command return; } - if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str())) - process_numlist(mask.c_str(), NULL, akick_view_callback, u, ci, &sent_header); + if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkickViewCallback(u, ci, mask.c_str()))->Process(); else { - for (i = 0; i < ci->GetAkickCount(); ++i) + bool SentHeader = false; + + for (unsigned i = 0; i < ci->GetAkickCount(); ++i) { - akick = ci->GetAkick(i); + AutoKick *akick = ci->GetAkick(i); - if (!akick->InUse) - continue; if (!mask.empty()) { if (!(akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false)) @@ -475,12 +474,19 @@ class CommandCSAKick : public Command if ((akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->nc->display, mask.c_str(), false)) continue; } - akick_view(u, i, ci, &sent_header); + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str()); + } + + AkickViewCallback::DoList(u, ci, i, akick); } - } - if (!sent_header) - notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); + if (!SentHeader) + notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str()); + } } void DoEnforce(User *u, ChannelInfo *ci, const std::vector<ci::string> ¶ms) @@ -524,7 +530,7 @@ class CommandCSAKick : public Command ci::string cmd = params[1]; ci::string mask = params.size() > 2 ? params[2] : ""; - ChannelInfo *ci = cs_findchan(chan.c_str()); + ChannelInfo *ci = cs_findchan(chan); if (mask.empty() && (cmd == "ADD" || cmd == "STICK" || cmd == "UNSTICK" || cmd == "DEL")) this->OnSyntaxError(u, cmd); @@ -564,6 +570,11 @@ class CommandCSAKick : public Command { syntax_error(Config.s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AKICK); + } }; @@ -577,13 +588,7 @@ class CSAKick : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSAKick()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AKICK); + this->AddCommand(ChanServ, new CommandCSAKick()); } }; diff --git a/src/core/cs_ban.c b/src/core/cs_ban.cpp index d0bbbfbb4..9aee9d1dc 100644 --- a/src/core/cs_ban.c +++ b/src/core/cs_ban.cpp @@ -17,7 +17,7 @@ class CommandCSBan : public Command { public: - CommandCSBan(const std::string &cname) : Command(cname, 2, 3) + CommandCSBan(const ci::string &cname) : Command(cname, 2, 3) { } @@ -62,9 +62,9 @@ class CommandCSBan : public Command */ } else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2)) { notice_lang(Config.s_ChanServ, u, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str()); - } else if (is_protected(u2)) { + } else if (u2->IsProtected()) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - } else { + else { char mask[BUFSIZE]; get_idealban(ci, u2, mask, sizeof(mask)); @@ -93,6 +93,11 @@ class CommandCSBan : public Command { syntax_error(Config.s_ChanServ, u, "BAN", CHAN_BAN_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_BAN); + } }; @@ -104,14 +109,8 @@ class CSBan : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSBan("BAN")); - this->AddCommand(CHANSERV, new CommandCSBan("KB")); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_BAN); + this->AddCommand(ChanServ, new CommandCSBan("BAN")); + this->AddCommand(ChanServ, new CommandCSBan("KB")); } }; diff --git a/src/core/cs_clear.c b/src/core/cs_clear.cpp index bb86e3b74..f331f7a24 100644 --- a/src/core/cs_clear.c +++ b/src/core/cs_clear.cpp @@ -161,6 +161,11 @@ class CommandCSClear : public Command { syntax_error(Config.s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_CLEAR); + } }; class CSClear : public Module @@ -171,13 +176,7 @@ class CSClear : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSClear()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_CLEAR); + this->AddCommand(ChanServ, new CommandCSClear()); } }; diff --git a/src/core/cs_drop.c b/src/core/cs_drop.cpp index b91fdc846..04b2f595f 100644 --- a/src/core/cs_drop.c +++ b/src/core/cs_drop.cpp @@ -48,7 +48,7 @@ class CommandCSDrop : public Command return MOD_CONT; } - if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)) && !u->Account()->HasCommand("chanserv/drop")) + if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop")) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -66,7 +66,8 @@ class CommandCSDrop : public Command if (ircd->chansqline && (ci->HasFlag(CI_FORBIDDEN))) { - ircdproto->SendSQLineDel(ci->name.c_str()); + XLine x(ci->name.c_str()); + ircdproto->SendSQLineDel(&x); } Alog() << Config.s_ChanServ << ": Channel " << ci->name << " dropped by " << u->GetMask() << " (founder: " @@ -78,8 +79,8 @@ class CommandCSDrop : public Command * drop the channel before issuing the wallops. */ if (Config.WallDrop) { - if ((level < ACCESS_FOUNDER) || (!IsRealFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER))) - ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan); + if ((level < ACCESS_FOUNDER) || (!IsFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER))) + ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan); } notice_lang(Config.s_ChanServ, u, CHAN_DROPPED, chan); @@ -103,6 +104,11 @@ class CommandCSDrop : public Command { syntax_error(Config.s_ChanServ, u, "DROP", CHAN_DROP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DROP); + } }; class CSDrop : public Module @@ -113,13 +119,7 @@ class CSDrop : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSDrop()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DROP); + this->AddCommand(ChanServ, new CommandCSDrop()); } }; diff --git a/src/core/cs_forbid.c b/src/core/cs_forbid.cpp index b47982a7e..d59be57b2 100644 --- a/src/core/cs_forbid.c +++ b/src/core/cs_forbid.cpp @@ -64,7 +64,7 @@ class CommandCSForbid : public Command if (reason) ci->forbidreason = sstrdup(reason); - if ((c = findchan(ci->name.c_str()))) + if ((c = findchan(ci->name))) { /* Before banning everyone, it might be prudent to clear +e and +I lists.. * to prevent ppl from rejoining.. ~ Viper */ @@ -78,16 +78,17 @@ class CommandCSForbid : public Command if (is_oper(uc->user)) continue; - c->Kick(findbot(Config.s_ChanServ), uc->user, "%s", reason ? reason : getstring(uc->user->Account(), CHAN_FORBID_REASON)); + c->Kick(ChanServ, uc->user, "%s", reason ? reason : getstring(uc->user->Account(), CHAN_FORBID_REASON)); } } if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); + ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); if (ircd->chansqline) { - ircdproto->SendSQLine(ci->name, reason ? reason : "Forbidden"); + XLine x(chan, "Forbidden"); + ircdproto->SendSQLine(&x); } Alog() << Config.s_ChanServ << ": " << u->nick << " set FORBID for channel " << ci->name; @@ -108,6 +109,11 @@ class CommandCSForbid : public Command { syntax_error(Config.s_ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_FORBID); + } }; class CSForbid : public Module @@ -118,13 +124,7 @@ class CSForbid : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSForbid()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_FORBID); + this->AddCommand(ChanServ, new CommandCSForbid()); } }; diff --git a/src/core/cs_getkey.c b/src/core/cs_getkey.cpp index a0937911b..dc89bbbd0 100644 --- a/src/core/cs_getkey.c +++ b/src/core/cs_getkey.cpp @@ -55,6 +55,11 @@ class CommandCSGetKey : public Command { syntax_error(Config.s_ChanServ, u, "GETKEY", CHAN_GETKEY_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_GETKEY); + } }; @@ -66,13 +71,7 @@ class CSGetKey : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSGetKey()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_GETKEY); + this->AddCommand(ChanServ, new CommandCSGetKey()); } }; diff --git a/src/core/cs_help.c b/src/core/cs_help.cpp index d975647b2..3fe704349 100644 --- a/src/core/cs_help.c +++ b/src/core/cs_help.cpp @@ -46,7 +46,7 @@ class CommandCSHelp : public Command } } else - mod_help_cmd(Config.s_ChanServ, u, CHANSERV, cmd.c_str()); + mod_help_cmd(ChanServ, u, cmd.c_str()); return MOD_CONT; } @@ -54,7 +54,8 @@ class CommandCSHelp : public Command void OnSyntaxError(User *u, const ci::string &subcommand) { notice_help(Config.s_ChanServ, u, CHAN_HELP); - FOREACH_MOD(I_OnChanServHelp, OnChanServHelp(u)); + for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it) + it->second->OnServHelp(u); if (Config.CSExpire >= 86400) notice_help(Config.s_ChanServ, u, CHAN_HELP_EXPIRES, Config.CSExpire / 86400); if (u->Account() && u->Account()->IsServicesOper()) @@ -71,7 +72,7 @@ class CSHelp : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSHelp()); + this->AddCommand(ChanServ, new CommandCSHelp()); } }; diff --git a/src/core/cs_info.c b/src/core/cs_info.cpp index 60e8ebf50..4e5bf9159 100644 --- a/src/core/cs_info.c +++ b/src/core/cs_info.cpp @@ -43,8 +43,8 @@ class CommandCSInfo : public Command ChannelInfo *ci; char buf[BUFSIZE]; struct tm *tm; - bool has_auspex = u->Account() && u->Account()->HasPriv("chanserv/auspex"); - int show_all = 0; + bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex"); + bool show_all = false; time_t expt; ci = cs_findchan(chan); @@ -64,7 +64,7 @@ class CommandCSInfo : public Command /* Should we show all fields? Only for sadmins and identified users */ if (!param.empty() && param == "ALL" && (check_access(u, ci, CA_INFO) || has_auspex)) - show_all = 1; + show_all = true; notice_lang(Config.s_ChanServ, u, CHAN_INFO_HEADER, chan); notice_lang(Config.s_ChanServ, u, CHAN_INFO_NO_FOUNDER, ci->founder->display); @@ -138,6 +138,8 @@ class CommandCSInfo : public Command notice_lang(Config.s_ChanServ, u, CHAN_X_SUSPENDED, ci->forbidby, (ci->forbidreason ? ci->forbidreason : getstring(u, NO_REASON))); } + FOREACH_MOD(I_OnChanInfo, OnChanInfo(u, ci, show_all)); + if (!show_all && (check_access(u, ci, CA_INFO) || has_auspex)) notice_lang(Config.s_ChanServ, u, NICK_INFO_FOR_MORE, Config.s_ChanServ, ci->name.c_str()); return MOD_CONT; @@ -146,7 +148,7 @@ class CommandCSInfo : public Command bool OnHelp(User *u, const ci::string &subcommand) { notice_lang(Config.s_ChanServ, u, CHAN_HELP_INFO); - if (u->Account() && u->Account()->HasPriv("chanserv/auspex")) + if (u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex")) notice_lang(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_INFO); return true; @@ -156,6 +158,11 @@ class CommandCSInfo : public Command { syntax_error(Config.s_ChanServ, u, "INFO", CHAN_INFO_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INFO); + } }; class CSInfo : public Module @@ -166,13 +173,7 @@ class CSInfo : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSInfo()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INFO); + this->AddCommand(ChanServ, new CommandCSInfo()); } }; diff --git a/src/core/cs_invite.c b/src/core/cs_invite.cpp index b71e487cc..40999af83 100644 --- a/src/core/cs_invite.c +++ b/src/core/cs_invite.cpp @@ -46,7 +46,7 @@ class CommandCSInvite : public Command u2 = u; else { - if (!(u2 = finduser(params[1].c_str()))) + if (!(u2 = finduser(params[1]))) { notice_lang(Config.s_ChanServ, u, NICK_X_NOT_IN_USE, params[1].c_str()); return MOD_CONT; @@ -74,6 +74,11 @@ class CommandCSInvite : public Command { syntax_error(Config.s_ChanServ, u, "INVITE", CHAN_INVITE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INVITE); + } }; class CSInvite : public Module @@ -84,13 +89,7 @@ class CSInvite : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSInvite()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INVITE); + this->AddCommand(ChanServ, new CommandCSInvite()); } }; diff --git a/src/core/cs_kick.c b/src/core/cs_kick.cpp index bce32d401..e28b1f176 100644 --- a/src/core/cs_kick.c +++ b/src/core/cs_kick.cpp @@ -17,7 +17,7 @@ class CommandCSKick : public Command { public: - CommandCSKick(const std::string& cname) : Command(cname, 2, 3) + CommandCSKick(const ci::string &cname) : Command(cname, 2, 3) { } @@ -56,9 +56,9 @@ class CommandCSKick : public Command } else if (!is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci))) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - } else if (is_protected(u2)) { + } else if (u2->IsProtected()) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - } else if (!c->FindUser(u2)) { + else if (!c->FindUser(u2)) { notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str()); } else { if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) @@ -79,6 +79,11 @@ class CommandCSKick : public Command { syntax_error(Config.s_ChanServ, u, "KICK", CHAN_KICK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_KICK); + } }; class CSKick : public Module @@ -89,14 +94,8 @@ class CSKick : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSKick("KICK")); - this->AddCommand(CHANSERV, new CommandCSKick("K")); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_KICK); + this->AddCommand(ChanServ, new CommandCSKick("KICK")); + this->AddCommand(ChanServ, new CommandCSKick("K")); } }; diff --git a/src/core/cs_list.c b/src/core/cs_list.cpp index cb86bb300..9e8ed1779 100644 --- a/src/core/cs_list.c +++ b/src/core/cs_list.cpp @@ -28,8 +28,7 @@ public: const char *pattern = params[0].c_str(); int spattern_size; char *spattern; - ChannelInfo *ci; - unsigned nchans, i; + unsigned nchans; char buf[BUFSIZE]; bool is_servadmin = u->Account()->HasCommand("chanserv/list"); int count = 0, from = 0, to = 0, tofree = 0; @@ -111,55 +110,56 @@ public: snprintf(spattern, spattern_size, "#%s", pattern); notice_lang(Config.s_ChanServ, u, CHAN_LIST_HEADER, pattern); - for (i = 0; i < 256; i++) + + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) { - for (ci = chanlists[i]; ci; ci = ci->next) + ChannelInfo *ci = it->second; + + if (!is_servadmin && ((ci->HasFlag(CI_PRIVATE)) + || (ci->HasFlag(CI_FORBIDDEN)) || (ci->HasFlag(CI_SUSPENDED)))) + continue; + if (forbidden && !ci->HasFlag(CI_FORBIDDEN)) + continue; + else if (suspended && !ci->HasFlag(CI_SUSPENDED)) + continue; + else if (channoexpire && !ci->HasFlag(CI_NO_EXPIRE)) + continue; + + if ((stricmp(pattern, ci->name.c_str()) == 0) + || (stricmp(spattern, ci->name.c_str()) == 0) + || Anope::Match(ci->name, pattern, false) + || Anope::Match(ci->name, spattern, false)) { - if (!is_servadmin && ((ci->HasFlag(CI_PRIVATE)) - || (ci->HasFlag(CI_FORBIDDEN)) || (ci->HasFlag(CI_SUSPENDED)))) - continue; - if (forbidden && !ci->HasFlag(CI_FORBIDDEN)) - continue; - else if (suspended && !ci->HasFlag(CI_SUSPENDED)) - continue; - else if (channoexpire && !ci->HasFlag(CI_NO_EXPIRE)) - continue; - - if ((stricmp(pattern, ci->name.c_str()) == 0) - || (stricmp(spattern, ci->name.c_str()) == 0) - || Anope::Match(ci->name, pattern, false) - || Anope::Match(ci->name, spattern, false)) + if ((((count + 1 >= from) && (count + 1 <= to)) + || ((from == 0) && (to == 0))) + && (++nchans <= Config.CSListMax)) { - if ((((count + 1 >= from) && (count + 1 <= to)) - || ((from == 0) && (to == 0))) - && (++nchans <= Config.CSListMax)) + char noexpire_char = ' '; + if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE))) + noexpire_char = '!'; + + if (ci->HasFlag(CI_FORBIDDEN)) + { + snprintf(buf, sizeof(buf), + "%-20s [Forbidden]", ci->name.c_str()); + } + else if (ci->HasFlag(CI_SUSPENDED)) { - char noexpire_char = ' '; - if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE))) - noexpire_char = '!'; - - if (ci->HasFlag(CI_FORBIDDEN)) - { - snprintf(buf, sizeof(buf), - "%-20s [Forbidden]", ci->name.c_str()); - } - else if (ci->HasFlag(CI_SUSPENDED)) - { - snprintf(buf, sizeof(buf), - "%-20s [Suspended]", ci->name.c_str()); - } - else - { - snprintf(buf, sizeof(buf), "%-20s %s", - ci->name.c_str(), ci->desc ? ci->desc : ""); - } - - u->SendMessage(Config.s_ChanServ, " %c%s", noexpire_char, buf); + snprintf(buf, sizeof(buf), + "%-20s [Suspended]", ci->name.c_str()); } - count++; + else + { + snprintf(buf, sizeof(buf), "%-20s %s", + ci->name.c_str(), ci->desc ? ci->desc : ""); + } + + u->SendMessage(Config.s_ChanServ, " %c%s", noexpire_char, buf); } + count++; } } + notice_lang(Config.s_ChanServ, u, CHAN_LIST_END, nchans > Config.CSListMax ? Config.CSListMax : nchans, nchans); delete [] spattern; @@ -178,6 +178,11 @@ public: { syntax_error(Config.s_ChanServ, u, "LIST", CHAN_LIST_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LIST); + } }; class CSList : public Module @@ -188,13 +193,7 @@ public: this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSList()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LIST); + this->AddCommand(ChanServ, new CommandCSList()); } }; diff --git a/src/core/cs_modes.c b/src/core/cs_modes.cpp index 3df93d912..67d38ba49 100644 --- a/src/core/cs_modes.c +++ b/src/core/cs_modes.cpp @@ -49,7 +49,7 @@ static CommandReturn do_util(User *u, ChannelMode *cm, const char *chan, const c notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci))) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (!set && is_protected(u2) && !is_same) + else if (!set && u2->IsProtected() && !is_same) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else if (!c->FindUser(u2)) notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str()); @@ -92,6 +92,11 @@ class CommandCSOp : public Command { syntax_error(Config.s_ChanServ, u, "OP", CHAN_OP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OP); + } }; @@ -119,6 +124,11 @@ class CommandCSDeOp : public Command { syntax_error(Config.s_ChanServ, u, "DEOP", CHAN_DEOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOP); + } }; @@ -146,6 +156,11 @@ class CommandCSVoice : public Command { syntax_error(Config.s_ChanServ, u, "VOICE", CHAN_VOICE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOICE); + } }; @@ -173,6 +188,11 @@ class CommandCSDeVoice : public Command { syntax_error(Config.s_ChanServ, u, "DEVOICE", CHAN_DEVOICE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEVOICE); + } }; @@ -205,6 +225,11 @@ class CommandCSHalfOp : public Command { syntax_error(Config.s_ChanServ, u, "HALFOP", CHAN_HALFOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HALFOP); + } }; @@ -238,6 +263,11 @@ class CommandCSDeHalfOp : public Command { syntax_error(Config.s_ChanServ, u, "DEHALFOP", CHAN_DEHALFOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEHALFOP); + } }; @@ -270,6 +300,11 @@ class CommandCSProtect : public Command { syntax_error(Config.s_ChanServ, u, "PROTECT", CHAN_PROTECT_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_PROTECT); + } }; class CommandCSDeProtect : public Command @@ -301,6 +336,11 @@ class CommandCSDeProtect : public Command { syntax_error(Config.s_ChanServ, u, "DEPROTECT", CHAN_DEPROTECT_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEPROTECT); + } }; class CommandCSOwner : public Command @@ -332,6 +372,11 @@ class CommandCSOwner : public Command { syntax_error(Config.s_ChanServ, u, "OWNER", CHAN_OWNER_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OWNER); + } }; class CommandCSDeOwner : public Command @@ -363,6 +408,11 @@ class CommandCSDeOwner : public Command { syntax_error(Config.s_ChanServ, u, "DEOWNER", CHAN_DEOWNER_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOWNER); + } }; @@ -375,76 +425,49 @@ class CSModes : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSOp()); - this->AddCommand(CHANSERV, new CommandCSDeOp()); - this->AddCommand(CHANSERV, new CommandCSVoice()); - this->AddCommand(CHANSERV, new CommandCSDeVoice()); + this->AddCommand(ChanServ, new CommandCSOp()); + this->AddCommand(ChanServ, new CommandCSDeOp()); + this->AddCommand(ChanServ, new CommandCSVoice()); + this->AddCommand(ChanServ, new CommandCSDeVoice()); - if (serv_uplink && is_sync(serv_uplink)) - OnUplinkSync(); + if (Me && Me->IsSynced()) + OnUplinkSync(NULL); Implementation i[] = { - I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp + I_OnUplinkSync, I_OnServerDisconnect }; - ModuleManager::Attach(i, this, 3); + ModuleManager::Attach(i, this, 2); } - void OnUplinkSync() + void OnUplinkSync(Server *) { if (ModeManager::FindChannelModeByName(CMODE_OWNER)) { - this->AddCommand(CHANSERV, new CommandCSOwner()); - this->AddCommand(CHANSERV, new CommandCSDeOwner()); + this->AddCommand(ChanServ, new CommandCSOwner()); + this->AddCommand(ChanServ, new CommandCSDeOwner()); } if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) { - this->AddCommand(CHANSERV, new CommandCSProtect()); - this->AddCommand(CHANSERV, new CommandCSDeProtect()); + this->AddCommand(ChanServ, new CommandCSProtect()); + this->AddCommand(ChanServ, new CommandCSDeProtect()); } if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) { - this->AddCommand(CHANSERV, new CommandCSHalfOp()); - this->AddCommand(CHANSERV, new CommandCSDeHalfOp()); + this->AddCommand(ChanServ, new CommandCSHalfOp()); + this->AddCommand(ChanServ, new CommandCSDeHalfOp()); } } void OnServerDisconnect() { - this->DelCommand(CHANSERV, "OWNER"); - this->DelCommand(CHANSERV, "DEOWNER"); - this->DelCommand(CHANSERV, "PROTECT"); - this->DelCommand(CHANSERV, "DEPROTECT"); - this->DelCommand(CHANSERV, "HALFOP"); - this->DelCommand(CHANSERV, "DEHALFOP"); - } - - void OnChanServHelp(User *u) - { - if (ModeManager::FindChannelModeByName(CMODE_OWNER)) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OWNER); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOWNER); - } - - if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_PROTECT); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEPROTECT); - } - - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OP); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOP); - - if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HALFOP); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEHALFOP); - } - - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOICE); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEVOICE); + this->DelCommand(ChanServ, FindCommand(ChanServ, "OWNER")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "DEOWNER")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "PROTECT")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "DEPROTECT")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "HALFOP")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "DEHALFOP")); } }; diff --git a/src/core/cs_register.c b/src/core/cs_register.cpp index 2c6531226..1706ac16e 100644 --- a/src/core/cs_register.c +++ b/src/core/cs_register.cpp @@ -44,8 +44,6 @@ class CommandCSRegister : public Command notice_lang(Config.s_ChanServ, u, CHAN_X_INVALID, chan); else if ((ci = cs_findchan(chan))) notice_lang(Config.s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan); - else if (!stricmp(chan, "#")) - notice_lang(Config.s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); else if (c && !c->HasUserStatus(u, CMODE_OP)) notice_lang(Config.s_ChanServ, u, CHAN_MUST_BE_CHANOP); else if (Config.CSMaxReg && u->Account()->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) @@ -114,6 +112,11 @@ class CommandCSRegister : public Command { syntax_error(Config.s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX); } + + void OnSyntaxError(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_REGISTER); + } }; class CSRegister : public Module @@ -125,13 +128,7 @@ class CSRegister : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSRegister()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_REGISTER); + this->AddCommand(ChanServ, new CommandCSRegister()); } }; diff --git a/src/core/cs_saset.cpp b/src/core/cs_saset.cpp new file mode 100644 index 000000000..29f7f7264 --- /dev/null +++ b/src/core/cs_saset.cpp @@ -0,0 +1,131 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSASet : public Command +{ + std::map<ci::string, Command *> subcommands; + + public: + CommandCSSASet(const ci::string &cname) : Command(cname, 2, 3) + { + } + + ~CommandCSSASet() + { + for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + { + delete it->second; + } + this->subcommands.clear(); + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (readonly) + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED); + return MOD_CONT; + } + + Command *c = this->FindCommand(params[1]); + + if (c) + { + ci::string cmdparams = cs_findchan(params[0])->name.c_str(); + for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it) + cmdparams += " " + *it; + mod_run_cmd(ChanServ, u, c, params[1], cmdparams); + } + else + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str()); + notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET"); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + if (subcommand.empty()) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SASET_HEAD); + for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + it->second->OnServHelp(u); + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL); + return true; + } + else + { + Command *c = this->FindCommand(subcommand); + + if (c) + { + return c->OnHelp(u, subcommand); + } + } + + return false; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SASET); + } + + bool AddSubcommand(Command *c) + { + return this->subcommands.insert(std::make_pair(c->name, c)).second; + } + + bool DelSubcommand(const ci::string &command) + { + return this->subcommands.erase(command); + } + + Command *FindCommand(const ci::string &subcommand) + { + std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand); + + if (it != this->subcommands.end()) + { + return it->second; + } + + return NULL; + } +}; + +class CSSASet : public Module +{ + public: + CSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + this->AddCommand(ChanServ, new CommandCSSASet("SASET")); + } +}; + +MODULE_INIT(CSSASet) diff --git a/src/core/cs_saset_noexpire.cpp b/src/core/cs_saset_noexpire.cpp new file mode 100644 index 000000000..8d9ce2e18 --- /dev/null +++ b/src/core/cs_saset_noexpire.cpp @@ -0,0 +1,85 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSASetNoexpire : public Command +{ + public: + CommandCSSASetNoexpire(const ci::string &cname) : Command(cname, 2, 2, "chanserv/saset/noexpire") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[0] == "ON") + { + ci->SetFlag(CI_NO_EXPIRE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str()); + } + else if (params[0] == "OFF") + { + ci->UnsetFlag(CI_NO_EXPIRE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "NOEXPIRE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET NOEXPIRE", CHAN_SET_NOEXPIRE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_NOEXPIRE); + } +}; + +class CSSetNoexpire : public Module +{ + public: + CSSetNoexpire(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetNoexpire("NOEXPIRE")); + } + + ~CSSetNoexpire() + { + Command *c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("NOEXPIRE"); + } +}; + +MODULE_INIT(CSSetNoexpire) diff --git a/src/core/cs_set.c b/src/core/cs_set.c deleted file mode 100644 index c964d26fc..000000000 --- a/src/core/cs_set.c +++ /dev/null @@ -1,839 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" -#include "hashcomp.h" - -class CommandCSSet : public Command -{ - private: - CommandReturn DoSetFounder(User * u, ChannelInfo * ci, const ci::string ¶m) - { - NickAlias *na = findnick(param.c_str()); - NickCore *nc, *nc0 = ci->founder; - - if (!na) - { - notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str()); - return MOD_CONT; - } - else if (na->HasFlag(NS_FORBIDDEN)) - { - notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str()); - return MOD_CONT; - } - - nc = na->nc; - if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) - { - notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, param.c_str()); - return MOD_CONT; - } - - Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display - << " to " << nc->display << " by " << u->GetMask(); - - /* Founder and successor must not be the same group */ - if (nc == ci->successor) - ci->successor = NULL; - - nc0->channelcount--; - ci->founder = nc; - nc->channelcount++; - - notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), param.c_str()); - return MOD_CONT; - } - - CommandReturn DoSetSuccessor(User * u, ChannelInfo * ci, const ci::string ¶m) - { - NickAlias *na; - NickCore *nc; - - if (!param.empty()) - { - na = findnick(param.c_str()); - - if (!na) - { - notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str()); - return MOD_CONT; - } - if (na->HasFlag(NS_FORBIDDEN)) - { - notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str()); - return MOD_CONT; - } - if (na->nc == ci->founder) - { - notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, param.c_str(), ci->name.c_str()); - return MOD_CONT; - } - nc = na->nc; - - } - else - nc = NULL; - - Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from " - << (ci->successor ? ci->successor->display : "none") - << " to " << (nc ? nc->display : "none") << " by " << u->GetMask(); - - ci->successor = nc; - - if (nc) - notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), param.c_str()); - else - notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str()); - - return MOD_CONT; - } - - CommandReturn DoSetDesc(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (ci->desc) - delete [] ci->desc; - ci->desc = sstrdup(param.c_str()); - notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), param.c_str()); - return MOD_CONT; - } - - CommandReturn DoSetURL(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (ci->url) - delete [] ci->url; - if (!param.empty()) - { - ci->url = sstrdup(param.c_str()); - notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), param.c_str()); - } - else - { - ci->url = NULL; - notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str()); - } - return MOD_CONT; - } - - CommandReturn DoSetEMail(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (ci->email) - delete [] ci->email; - if (!param.empty()) - { - ci->email = sstrdup(param.c_str()); - notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), param.c_str()); - } - else - { - ci->email = NULL; - notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str()); - } - return MOD_CONT; - } - - CommandReturn DoSetEntryMsg(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (ci->entry_message) - delete [] ci->entry_message; - if (!param.empty()) - { - ci->entry_message = sstrdup(param.c_str()); - notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), param.c_str()); - } - else - { - ci->entry_message = NULL; - notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str()); - } - return MOD_CONT; - } - - CommandReturn DoSetMLock(User * u, ChannelInfo * ci, const char *modes) - { - int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */ - unsigned char mode; - ChannelMode *cm; - ChannelModeParam *cmp; - - ci->ClearMLock(); - - if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) - ci->SetMLock(CMODE_REGISTERED, true); - - ci->ClearParams(); - - std::string params(modes ? modes : ""), param; - unsigned space = params.find(' '); - if (space != std::string::npos) - { - param = params.substr(space + 1); - params = params.substr(0, space); - modes = params.c_str(); - } - spacesepstream modeparams(param); - - while (modes && (mode = *modes++)) { - switch (mode) { - case '+': - add = 1; - continue; - case '-': - add = 0; - continue; - default: - if (add < 0) - continue; - } - - if ((cm = ModeManager::FindChannelModeByChar(mode))) - { - if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u)) - { - notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode); - } - else if (add) - { - ci->RemoveMLock(cm->Name); - - if (cm->Type == MODE_PARAM) - { - cmp = dynamic_cast<ChannelModeParam *>(cm); - - if (!modeparams.GetToken(param)) - continue; - - if (!cmp->IsValid(param)) - continue; - - ci->SetMLock(cmp->Name, true, param); - } - else - { - ci->SetMLock(cm->Name, true); - } - } - else - { - ci->SetMLock(cm->Name, false); - } - } - else - notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode); - } /* while (*modes) */ - - if (ModeManager::FindChannelModeByName(CMODE_REDIRECT)) { - /* We can't mlock +L if +l is not mlocked as well. */ - if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true)) - { - ci->RemoveMLock(CMODE_REDIRECT); - notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED); - } - } - - /* Some ircd we can't set NOKNOCK without INVITE */ - /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */ - if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i) { - if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true)) - { - ci->RemoveMLock(CMODE_NOKNOCK); - notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED); - } - } - - /* Since we always enforce mode r there is no way to have no - * mode lock at all. - */ - if (get_mlock_modes(ci, 0)) { - notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(), - get_mlock_modes(ci, 0)); - } - - /* Implement the new lock. */ - if (ci->c) - check_modes(ci->c); - return MOD_CONT; - } - - CommandReturn DoSetBanType(User * u, ChannelInfo * ci, const char *param) - { - char *endptr; - - int16 bantype = strtol(param, &endptr, 10); - - if (*endptr != 0 || bantype < 0 || bantype > 3) { - notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, param); - } else { - ci->bantype = bantype; - notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), - ci->bantype); - } - return MOD_CONT; - } - - CommandReturn DoSetKeepTopic(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_KEEPTOPIC); - notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_KEEPTOPIC); - notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "KEEPTOPIC"); - - return MOD_CONT; - } - - CommandReturn DoSetTopicLock(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_TOPICLOCK); - notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_TOPICLOCK); - notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "TOPICLOCK"); - - return MOD_CONT; - } - - CommandReturn DoSetPrivate(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_PRIVATE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_PRIVATE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "PRIVATE"); - - return MOD_CONT; - } - - CommandReturn DoSetSecureOps(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_SECUREOPS); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_SECUREOPS); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "SECUREOPS"); - - return MOD_CONT; - } - - CommandReturn DoSetSecureFounder(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_SECUREFOUNDER); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_SECUREFOUNDER); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "SECUREFOUNDER"); - - return MOD_CONT; - } - - CommandReturn DoSetRestricted(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_RESTRICTED); - if (ci->levels[CA_NOJOIN] < 0) - ci->levels[CA_NOJOIN] = 0; - notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_RESTRICTED); - if (ci->levels[CA_NOJOIN] >= 0) - ci->levels[CA_NOJOIN] = -2; - notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "RESTRICTED"); - - return MOD_CONT; - } - - CommandReturn DoSetSecure(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_SECURE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_SECURE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "SECURE"); - - return MOD_CONT; - } - - CommandReturn DoSetSignKick(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_SIGNKICK); - ci->UnsetFlag(CI_SIGNKICK_LEVEL); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str()); - } - else if (param == "LEVEL") - { - ci->SetFlag(CI_SIGNKICK_LEVEL); - ci->UnsetFlag(CI_SIGNKICK); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_SIGNKICK); - ci->UnsetFlag(CI_SIGNKICK_LEVEL); - notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "SIGNKICK"); - - return MOD_CONT; - } - - CommandReturn DoSetOpNotice(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_OPNOTICE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_OPNOTICE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "OPNOTICE"); - - return MOD_CONT; - } - -#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)])) - - CommandReturn DoSetXOP(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - if (!(ci->HasFlag(CI_XOP))) - { - ChanAccess *access; - - for (unsigned i = 0; i < ci->GetAccessCount(); i++) - { - access = ci->GetAccess(i); - if (!access->in_use) - continue; - /* This will probably cause wrong levels to be set, but hey, - * it's better than losing it altogether. - */ - if (access->level == ACCESS_QOP) - access->level = ACCESS_QOP; - else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET)) - access->level = ACCESS_SOP; - else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME)) - access->level = ACCESS_AOP; - else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP) || CHECKLEV(CA_HALFOPME))) - access->level = ACCESS_HOP; - else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME)) - access->level = ACCESS_VOP; - else - { - ci->EraseAccess(i); - } - } - - /* The above may have set an access entry to not be in use, this will clean that up. */ - ci->CleanAccess(); - - reset_levels(ci); - ci->SetFlag(CI_XOP); - } - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_XOP); - - Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name; - notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "XOP"); - - return MOD_CONT; - } - -#undef CHECKLEV - - CommandReturn DoSetPeace(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (param == "ON") - { - ci->SetFlag(CI_PEACE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_PEACE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "PEACE"); - - return MOD_CONT; - } - - CommandReturn DoSetPersist(User *u, ChannelInfo *ci, const ci::string ¶m) - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM); - - if (param == "ON") - { - if (!ci->HasFlag(CI_PERSIST)) - { - ci->SetFlag(CI_PERSIST); - - /* Channel doesn't exist, create it internally */ - if (!ci->c) - { - new Channel(ci->name); - if (ci->bi) - bot_join(ci); - } - - /* No botserv bot, no channel mode */ - if (!ci->bi && !cm) - { - /* Give them ChanServ - * Yes, this works fine with no Config.s_BotServ - */ - findbot(Config.s_ChanServ)->Assign(NULL, ci); - } - - /* Set the perm mode */ - if (cm && ci->c && !ci->c->HasMode(CMODE_PERM)) - { - ci->c->SetMode(NULL, cm); - } - } - - notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - if (ci->HasFlag(CI_PERSIST)) - { - ci->UnsetFlag(CI_PERSIST); - - /* Unset perm mode */ - if (cm && ci->c && ci->c->HasMode(CMODE_PERM)) - ci->c->RemoveMode(NULL, cm); - if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1) - ircdproto->SendPart(ci->bi, ci->c, NULL); - - /* No channel mode, no BotServ, but using ChanServ as the botserv bot - * which was assigned when persist was set on - */ - if (!cm && !Config.s_BotServ && ci->bi) - { - /* Unassign bot */ - findbot(Config.s_ChanServ)->UnAssign(NULL, ci); - } - - if (ci->c && ci->c->users.empty()) - delete ci->c; - } - - notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "PERSIST"); - - return MOD_CONT; - } - - CommandReturn DoSetNoExpire(User * u, ChannelInfo * ci, const ci::string ¶m) - { - if (!u->Account()->HasCommand("chanserv/set/noexpire")) - { - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - return MOD_CONT; - } - if (param == "ON") - { - ci->SetFlag(CI_NO_EXPIRE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str()); - } - else if (param == "OFF") - { - ci->UnsetFlag(CI_NO_EXPIRE); - notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str()); - } - else - this->OnSyntaxError(u, "NOEXPIRE"); - - return MOD_CONT; - } - - public: - CommandCSSet() : Command("SET", 2, 3) - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - const char *chan = params[0].c_str(); - ci::string cmd = params[1]; - ci::string param = params.size() > 2 ? params[2] : ""; - ChannelInfo *ci = cs_findchan(chan); - bool is_servadmin = u->Account()->HasPriv("chanserv/set"); - - if (readonly) { - notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED); - return MOD_CONT; - } - - if (param.empty() && cmd != "SUCCESSOR" && cmd != "URL" && cmd != "EMAIL" && cmd != "ENTRYMSG" && cmd != "MLOCK") - this->OnSyntaxError(u, cmd); - else if (!is_servadmin && !check_access(u, ci, CA_SET)) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (cmd == "FOUNDER") - { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else - DoSetFounder(u, ci, param); - } - else if (cmd == "SUCCESSOR") - { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else - DoSetSuccessor(u, ci, param); - } - else if (cmd == "DESC") - DoSetDesc(u, ci, param); - else if (cmd == "URL") - DoSetURL(u, ci, param); - else if (cmd == "EMAIL") - DoSetEMail(u, ci, param); - else if (cmd == "ENTRYMSG") - DoSetEntryMsg(u, ci, param); - else if (cmd == "TOPIC") - notice_lang(Config.s_ChanServ, u, OBSOLETE_COMMAND, "TOPIC"); - else if (cmd == "BANTYPE") - DoSetBanType(u, ci, param.c_str()); - else if (cmd == "MLOCK") - DoSetMLock(u, ci, param.c_str()); - else if (cmd == "KEEPTOPIC") - DoSetKeepTopic(u, ci, param); - else if (cmd == "TOPICLOCK") - DoSetTopicLock(u, ci, param); - else if (cmd == "PRIVATE") - DoSetPrivate(u, ci, param); - else if (cmd == "SECUREOPS") - DoSetSecureOps(u, ci, param); - else if (cmd == "SECUREFOUNDER") - { - if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci))) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else - DoSetSecureFounder(u, ci, param); - } - else if (cmd == "RESTRICTED") - DoSetRestricted(u, ci, param); - else if (cmd == "SECURE") - DoSetSecure(u, ci, param); - else if (cmd == "SIGNKICK") - DoSetSignKick(u, ci, param); - else if (cmd == "OPNOTICE") - DoSetOpNotice(u, ci, param); - else if (cmd == "XOP") - { - if (!findModule("cs_xop")) - notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, cmd.c_str()); - else - DoSetXOP(u, ci, param); - } - else if (cmd == "PEACE") - DoSetPeace(u, ci, param); - else if (cmd == "PERSIST") - DoSetPersist(u, ci, param); - else if (cmd == "NOEXPIRE") - DoSetNoExpire(u, ci, param); - else - { - notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, cmd.c_str()); - notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET"); - } - - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - if (subcommand.empty()) - { - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET); - if (u->Account() && u->Account()->IsServicesOper()) - notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET); - } - else if (subcommand == "FOUNDER") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER); - else if (subcommand == "SUCCESSOR") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR); - else if (subcommand == "DESC") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC); - else if (subcommand == "URL") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL); - else if (subcommand == "EMAIL") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL); - else if (subcommand == "ENTRYMSG") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG); - else if (subcommand == "BANTYPE") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE); - else if (subcommand == "PRIVATE") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE); - else if (subcommand == "KEEPTOPIC") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC); - else if (subcommand == "TOPICLOCK") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK); - else if (subcommand == "MLOCK") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK); - else if (subcommand == "RESTRICTED") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED); - else if (subcommand == "SECURE") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, Config.s_NickServ); - else if (subcommand == "SECUREOPS") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS); - else if (subcommand == "SECUREFOUNDER") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER); - else if (subcommand == "SIGNKICK") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK); - else if (subcommand == "OPNOTICE") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE); - else if (subcommand == "XOP") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP); - else if (subcommand == "PEACE") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE); - else if (subcommand == "PERSIST") - notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST); - else if (subcommand == "NOEXPIRE") - notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE); - else - return false; - - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - int reply = CHAN_SET_SYNTAX; - ci::string command = "SET"; - - if (!subcommand.empty()) - { - if (subcommand == "KEEPTOPIC") - reply = CHAN_SET_KEEPTOPIC_SYNTAX; - else if (subcommand == "TOPICLOCK") - reply = CHAN_SET_TOPICLOCK_SYNTAX; - else if (subcommand == "PRIVATE") - reply = CHAN_SET_PRIVATE_SYNTAX; - else if (subcommand == "SECUREOPS") - reply = CHAN_SET_SECUREOPS_SYNTAX; - else if (subcommand == "SECUREFOUNDER") - reply = CHAN_SET_SECUREFOUNDER_SYNTAX; - else if (subcommand == "RESTRICTED") - reply = CHAN_SET_RESTRICTED_SYNTAX; - else if (subcommand == "SECURE") - reply = CHAN_SET_SECURE_SYNTAX; - else if (subcommand == "SIGNKICK") - reply = CHAN_SET_SIGNKICK_SYNTAX; - else if (subcommand == "OPNOTICE") - reply = CHAN_SET_OPNOTICE_SYNTAX; - else if (subcommand == "XOP") - reply = CHAN_SET_XOP_SYNTAX; - else if (subcommand == "PEACE") - reply = CHAN_SET_PEACE_SYNTAX; - else if (subcommand == "PERSIST") - reply = CHAN_SET_PERSIST_SYNTAX; - else if (subcommand == "NOEXPIRE") - reply = CHAN_SET_NOEXPIRE_SYNTAX; - - if (reply != CHAN_SET_SYNTAX) - command += " " + subcommand; - } - - syntax_error(Config.s_ChanServ, u, command.c_str(), reply); - } -}; - -class CSSet : public Module -{ - public: - CSSet(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSSet()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET); - } -}; - -MODULE_INIT(CSSet) diff --git a/src/core/cs_set.cpp b/src/core/cs_set.cpp new file mode 100644 index 000000000..c11a1c102 --- /dev/null +++ b/src/core/cs_set.cpp @@ -0,0 +1,136 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSet : public Command +{ + std::map<ci::string, Command *> subcommands; + + public: + CommandCSSet(const ci::string &cname) : Command(cname, 2, 3) + { + } + + ~CommandCSSet() + { + for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + { + delete it->second; + } + this->subcommands.clear(); + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (readonly) + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED); + return MOD_CONT; + } + if (!check_access(u, cs_findchan(params[0]), CA_SET)) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + + Command *c = this->FindCommand(params[1]); + + if (c) + { + ci::string cmdparams = cs_findchan(params[0])->name.c_str(); + for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it) + cmdparams += " " + *it; + mod_run_cmd(ChanServ, u, c, params[1], cmdparams); + } + else + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str()); + notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET"); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + if (subcommand.empty()) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_HEAD); + for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + it->second->OnServHelp(u); + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL); + return true; + } + else + { + Command *c = this->FindCommand(subcommand); + + if (c) + { + return c->OnHelp(u, subcommand); + } + } + + return false; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET); + } + + bool AddSubcommand(Command *c) + { + return this->subcommands.insert(std::make_pair(c->name, c)).second; + } + + bool DelSubcommand(const ci::string &command) + { + return this->subcommands.erase(command); + } + + Command *FindCommand(const ci::string &subcommand) + { + std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand); + + if (it != this->subcommands.end()) + { + return it->second; + } + + return NULL; + } +}; + +class CSSet : public Module +{ + public: + CSSet(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + this->AddCommand(ChanServ, new CommandCSSet("SET")); + } +}; + +MODULE_INIT(CSSet) diff --git a/src/core/cs_set_bantype.cpp b/src/core/cs_set_bantype.cpp new file mode 100644 index 000000000..985c6f1e6 --- /dev/null +++ b/src/core/cs_set_bantype.cpp @@ -0,0 +1,113 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetBanType : public Command +{ + public: + CommandCSSetBanType(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + char *endptr; + + int16 bantype = strtol(params[1].c_str(), &endptr, 10); + + if (*endptr != 0 || bantype < 0 || bantype > 3) + notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, params[1].c_str()); + else + { + ci->bantype = bantype; + notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), ci->bantype); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_BANTYPE); + } +}; + +class CommandCSSASetBanType : public CommandCSSetBanType +{ + public: + CommandCSSASetBanType(const ci::string &cname) : CommandCSSetBanType(cname, "chanserv/saset/bantype") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetBanType : public Module +{ + public: + CSSetBanType(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetBanType("BANTYPE")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetBanType("BANTYPE")); + } + + ~CSSetBanType() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("BANTYPE"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("BANTYPE"); + } +}; + +MODULE_INIT(CSSetBanType) diff --git a/src/core/cs_set_description.cpp b/src/core/cs_set_description.cpp new file mode 100644 index 000000000..44e6090bf --- /dev/null +++ b/src/core/cs_set_description.cpp @@ -0,0 +1,107 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetDescription : public Command +{ + public: + CommandCSSetDescription(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (ci->desc) + delete [] ci->desc; + ci->desc = sstrdup(params[1].c_str()); + + notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), ci->desc); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_DESC); + } +}; + +class CommandCSSASetDescription : public CommandCSSetDescription +{ + public: + CommandCSSASetDescription(const ci::string &cname) : CommandCSSetDescription(cname, "chanserv/saset/description") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetDescription : public Module +{ + public: + CSSetDescription(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetDescription("DESC")); + + c = FindCommand(ChanServ, "SASEt"); + if (c) + c->AddSubcommand(new CommandCSSASetDescription("DESC")); + } + + ~CSSetDescription() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("DESC"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("DESC"); + } +}; + +MODULE_INIT(CSSetDescription) diff --git a/src/core/cs_set_email.cpp b/src/core/cs_set_email.cpp new file mode 100644 index 000000000..d226a3b06 --- /dev/null +++ b/src/core/cs_set_email.cpp @@ -0,0 +1,106 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetEMail : public Command +{ + public: + CommandCSSetEMail(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (ci->email) + delete [] ci->email; + if (params.size() > 1) + { + ci->email = sstrdup(params[1].c_str()); + notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), ci->email); + } + else + { + ci->email = NULL; + notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str()); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_EMAIL); + } +}; + +class CommandCSSASetEMail : public CommandCSSetEMail +{ + public: + CommandCSSASetEMail(const ci::string &cname) : CommandCSSetEMail(cname, "chanserv/saset/email") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + /// XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetEMail : public Module +{ + public: + CSSetEMail(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetEMail("EMAIL")); + } + + ~CSSetEMail() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("EMAIL"); + } +}; + +MODULE_INIT(CSSetEMail) diff --git a/src/core/cs_set_entrymsg.cpp b/src/core/cs_set_entrymsg.cpp new file mode 100644 index 000000000..b7c223546 --- /dev/null +++ b/src/core/cs_set_entrymsg.cpp @@ -0,0 +1,114 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetEntryMsg : public Command +{ + public: + CommandCSSetEntryMsg(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (ci->entry_message) + delete [] ci->entry_message; + if (params.size() > 1) + { + ci->entry_message = sstrdup(params[1].c_str()); + notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), ci->entry_message); + } + else + { + ci->entry_message = NULL; + notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str()); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SEt"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_ENTRYMSG); + } +}; + +class CommandCSSASetEntryMsg : public CommandCSSetEntryMsg +{ + public: + CommandCSSASetEntryMsg(const ci::string &cname) : CommandCSSetEntryMsg(cname, "/chanserv/saset/entrymsg") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetEntryMsg : public Module +{ + public: + CSSetEntryMsg(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetEntryMsg("ENTRYMSG")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetEntryMsg("ENTRYMSG")); + } + + ~CSSetEntryMsg() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("ENTRYMSG"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("ENTRYMSG"); + } +}; + +MODULE_INIT(CSSetEntryMsg) diff --git a/src/core/cs_set_founder.cpp b/src/core/cs_set_founder.cpp new file mode 100644 index 000000000..6a456a0f6 --- /dev/null +++ b/src/core/cs_set_founder.cpp @@ -0,0 +1,142 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetFounder : public Command +{ + public: + CommandCSSetFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (this->permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + NickAlias *na = findnick(params[1]); + NickCore *nc, *nc0 = ci->founder; + + + if (!na) + { + notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str()); + return MOD_CONT; + } + else if (na->HasFlag(NS_FORBIDDEN)) + { + notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick); + return MOD_CONT; + } + + nc = na->nc; + if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, na->nick); + return MOD_CONT; + } + + Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display + << " to " << nc->display << " by " << u->GetMask(); + + /* Founder and successor must not be the same group */ + if (nc == ci->successor) + ci->successor = NULL; + + nc0->channelcount--; + ci->founder = nc; + nc->channelcount++; + + notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), na->nick); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_FOUNDER); + } +}; + +class CommandCSSASetFounder : public CommandCSSetFounder +{ + public: + CommandCSSASetFounder(const ci::string &cname) : CommandCSSetFounder(cname, "chanserv/saset/founder") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SASET"); + return true; + } + + void OnSyntaxError(User *u) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetFounder : public Module +{ + public: + CSSetFounder(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetFounder("FOUNDER")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetFounder("FOUNDER")); + } + + ~CSSetFounder() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("FOUNDER"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("FOUNDER"); + } +}; + +MODULE_INIT(CSSetFounder) diff --git a/src/core/cs_set_keeptopic.cpp b/src/core/cs_set_keeptopic.cpp new file mode 100644 index 000000000..87a4660cf --- /dev/null +++ b/src/core/cs_set_keeptopic.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetKeepTopic : public Command +{ + public: + CommandCSSetKeepTopic(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_KEEPTOPIC); + notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_KEEPTOPIC); + notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "KEEPTOPIC"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SET_KEEPTOPIC_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_KEEPTOPIC); + } +}; + +class CommandCSSASetKeepTopic : public CommandCSSetKeepTopic +{ + public: + CommandCSSASetKeepTopic(const ci::string &cname) : CommandCSSetKeepTopic(cname, "chanserv/saset/keeptopic") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SASET_KEEPTOPIC_SYNTAX); + } +}; + +class CSSetKeepTopic : public Module +{ + public: + CSSetKeepTopic(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetKeepTopic("KEEPTOPIC")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetKeepTopic("KEEPTOPIC")); + } + + ~CSSetKeepTopic() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("KEEPTOPIC"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("KEEPTOPIC"); + } +}; + +MODULE_INIT(CSSetKeepTopic) diff --git a/src/core/cs_set_mlock.cpp b/src/core/cs_set_mlock.cpp new file mode 100644 index 000000000..d75363ac4 --- /dev/null +++ b/src/core/cs_set_mlock.cpp @@ -0,0 +1,197 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetMLock : public Command +{ + public: + CommandCSSetMLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 0, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */ + unsigned char mode; + ChannelMode *cm; + unsigned paramcount = 2; + + ci->ClearMLock(); + ci->ClearParams(); + + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) + ci->SetMLock(CMODE_REGISTERED, true); + + const char *modes = params[1].c_str(); + while (modes && (mode = *modes++)) + { + switch (mode) { + case '+': + add = 1; + continue; + case '-': + add = 0; + continue; + default: + if (add < 0) + continue; + } + + if ((cm = ModeManager::FindChannelModeByChar(mode))) + { + if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u)) + { + notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode); + } + else if (add) + { + ci->RemoveMLock(cm->Name); + + if (cm->Type == MODE_PARAM) + { + if (paramcount >= params.size()) + continue; + + std::string param = params[paramcount].c_str(); + + ChannelModeParam *cmp = dynamic_cast<ChannelModeParam *>(cm); + + if (!cmp || !cmp->IsValid(param)) + continue; + + ci->SetMLock(cmp->Name, true, param); + } + else + { + ci->SetMLock(cm->Name, true); + } + } + else + { + ci->SetMLock(cm->Name, false); + } + } + else + notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode); + } /* while (*modes) */ + + if (ModeManager::FindChannelModeByName(CMODE_REDIRECT)) + { + /* We can't mlock +L if +l is not mlocked as well. */ + if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true)) + { + ci->RemoveMLock(CMODE_REDIRECT); + notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED); + } + } + + /* Some ircd we can't set NOKNOCK without INVITE */ + /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */ + if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i) + { + if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true)) + { + ci->RemoveMLock(CMODE_NOKNOCK); + notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED); + } + } + + /* Since we always enforce mode r there is no way to have no + * mode lock at all. + */ + if (get_mlock_modes(ci, 0)) { + notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(), get_mlock_modes(ci, 0)); + } + + /* Implement the new lock. */ + if (ci->c) + check_modes(ci->c); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_MLOCK); + } +}; + +class CommandCSSASetMLock : public CommandCSSetMLock +{ + public: + CommandCSSASetMLock(const ci::string &cname) : CommandCSSetMLock(cname, "chanserv/saset/mlock") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX); + } +}; + +class CSSetMLock : public Module +{ + public: + CSSetMLock(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetMLock("MLOCK")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetMLock("MLOCK")); + } + + ~CSSetMLock() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("MLOCK"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("MLOCK"); + } +}; + +MODULE_INIT(CSSetMLock) diff --git a/src/core/cs_set_opnotice.cpp b/src/core/cs_set_opnotice.cpp new file mode 100644 index 000000000..b889869bd --- /dev/null +++ b/src/core/cs_set_opnotice.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetOpNotice : public Command +{ + public: + CommandCSSetOpNotice(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_OPNOTICE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_OPNOTICE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "OPNOTICE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SET_OPNOTICE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_OPNOTICE); + } +}; + +class CommandCSSASetOpNotice : public CommandCSSetOpNotice +{ + public: + CommandCSSASetOpNotice(const ci::string &cname) : CommandCSSetOpNotice(cname, "chanserv/saset/opnotice") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SASET_OPNOTICE_SYNTAX); + } +}; + +class CSSetOpNotice : public Module +{ + public: + CSSetOpNotice(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetOpNotice("OPNOTICE")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetOpNotice("OPNOTICE")); + } + + ~CSSetOpNotice() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("OPNOTICE"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("OPNOTICE"); + } +}; + +MODULE_INIT(CSSetOpNotice) diff --git a/src/core/cs_set_peace.cpp b/src/core/cs_set_peace.cpp new file mode 100644 index 000000000..05cf5f863 --- /dev/null +++ b/src/core/cs_set_peace.cpp @@ -0,0 +1,114 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetPeace : public Command +{ + public: + CommandCSSetPeace(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_PEACE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_PEACE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str()); + } + else + { + this->OnSyntaxError(u, "PEACE"); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET PEACE", CHAN_SET_PEACE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PEACE, "SET"); + } +}; + +class CommandCSSASetPeace : public CommandCSSetPeace +{ + public: + CommandCSSASetPeace(const ci::string &cname) : CommandCSSetPeace(cname, "chanserv/saset/peace") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET PEACE", CHAN_SASET_PEACE_SYNTAX); + } +}; + +class CSSetPeace : public Module +{ + public: + CSSetPeace(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetPeace("PEACE")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetPeace("PEACE")); + } + + ~CSSetPeace() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("PEACE"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("PEACE"); + } +}; + +MODULE_INIT(CSSetPeace) diff --git a/src/core/cs_set_persist.cpp b/src/core/cs_set_persist.cpp new file mode 100644 index 000000000..0e713c715 --- /dev/null +++ b/src/core/cs_set_persist.cpp @@ -0,0 +1,163 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetPersist : public Command +{ + public: + CommandCSSetPersist(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM); + + if (params[0] == "ON") + { + if (!ci->HasFlag(CI_PERSIST)) + { + ci->SetFlag(CI_PERSIST); + + /* Channel doesn't exist, create it internally */ + if (!ci->c) + { + new Channel(ci->name); + if (ci->bi) + bot_join(ci); + } + + /* No botserv bot, no channel mode */ + if (!ci->bi && !cm) + { + /* Give them ChanServ + * Yes, this works fine with no Config.s_BotServ + */ + ChanServ->Assign(NULL, ci); + } + + /* Set the perm mode */ + if (cm && ci->c && !ci->c->HasMode(CMODE_PERM)) + { + ci->c->SetMode(NULL, cm); + } + } + + notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str()); + } + else if (params[0] == "OFF") + { + if (ci->HasFlag(CI_PERSIST)) + { + ci->UnsetFlag(CI_PERSIST); + + /* Unset perm mode */ + if (cm && ci->c && ci->c->HasMode(CMODE_PERM)) + ci->c->RemoveMode(NULL, cm); + if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1) + ircdproto->SendPart(ci->bi, ci->c, NULL); + + /* No channel mode, no BotServ, but using ChanServ as the botserv bot + * which was assigned when persist was set on + */ + if (!cm && !Config.s_BotServ && ci->bi) + { + /* Unassign bot */ + ChanServ->UnAssign(NULL, ci); + } + + if (ci->c && ci->c->users.empty()) + delete ci->c; + } + + notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "PERSIST"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET PERSIST", CHAN_SET_PERSIST_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PERSIST); + } +}; + +class CommandCSSASetPersist : public CommandCSSetPersist +{ + public: + CommandCSSASetPersist(const ci::string &cname) : CommandCSSetPersist(cname, "chanserv/saset/persist") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET PERSIST", CHAN_SASET_PERSIST_SYNTAX); + } +}; + +class CSSetPersist : public Module +{ + public: + CSSetPersist(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetPersist("PERSIST")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetPersist("PERSIST")); + } + + ~CSSetPersist() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("PERSIST"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("PERSIST"); + } +}; + +MODULE_INIT(CSSetPersist) diff --git a/src/core/cs_set_private.cpp b/src/core/cs_set_private.cpp new file mode 100644 index 000000000..9f96828df --- /dev/null +++ b/src/core/cs_set_private.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetPrivate : public Command +{ + public: + CommandCSSetPrivate(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_PRIVATE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_PRIVATE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "PRIVATE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET PRIVATE", CHAN_SET_PRIVATE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PRIVATE); + } +}; + +class CommandCSSASetPrivate : public CommandCSSetPrivate +{ + public: + CommandCSSASetPrivate(const ci::string &cname) : CommandCSSetPrivate(cname, "chanserv/saset/private") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET PRIVATE", CHAN_SASET_PRIVATE_SYNTAX); + } +}; + +class CSSetPrivate : public Module +{ + public: + CSSetPrivate(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetPrivate("PRIVATE")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetPrivate("PRIVATE")); + } + + ~CSSetPrivate() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("PRIVATE"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("PRIVATE"); + } +}; + +MODULE_INIT(CSSetPrivate) diff --git a/src/core/cs_set_restricted.cpp b/src/core/cs_set_restricted.cpp new file mode 100644 index 000000000..7e0cc42b3 --- /dev/null +++ b/src/core/cs_set_restricted.cpp @@ -0,0 +1,116 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetRestricted : public Command +{ + public: + CommandCSSetRestricted(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_RESTRICTED); + if (ci->levels[CA_NOJOIN] < 0) + ci->levels[CA_NOJOIN] = 0; + notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_RESTRICTED); + if (ci->levels[CA_NOJOIN] >= 0) + ci->levels[CA_NOJOIN] = -2; + notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "RESTRICTED"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET RESTRICTED", CHAN_SET_RESTRICTED_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_RESTRICTED); + } +}; + +class CommandCSSASetRestricted : public CommandCSSetRestricted +{ + public: + CommandCSSASetRestricted(const ci::string &cname) : CommandCSSetRestricted(cname, "chanserv/saset/restricted") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET RESTRICTED", CHAN_SASET_RESTRICTED_SYNTAX); + } +}; + +class CSSetRestricted : public Module +{ + public: + CSSetRestricted(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetRestricted("RESTRICTED")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetRestricted("RESTRICTED")); + } + + ~CSSetRestricted() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("RESTRICTED"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("RESTRICTED"); + } +}; + +MODULE_INIT(CSSetRestricted) diff --git a/src/core/cs_set_secure.cpp b/src/core/cs_set_secure.cpp new file mode 100644 index 000000000..bdcffdb21 --- /dev/null +++ b/src/core/cs_set_secure.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetSecure : public Command +{ + public: + CommandCSSetSecure(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_SECURE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_SECURE); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "SECURE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET SECURE", CHAN_SET_SECURE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECURE); + } +}; + +class CommandCSSASetSecure : public CommandCSSetSecure +{ + public: + CommandCSSASetSecure(const ci::string &cname) : CommandCSSetSecure(cname, "chanserv/saset/secure") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET SECURE", CHAN_SASET_SECURE_SYNTAX); + } +}; + +class CSSetSecure : public Module +{ + public: + CSSetSecure(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetSecure("SECURE")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetSecure("SECURE")); + } + + ~CSSetSecure() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("SECURE"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("SECURE"); + } +}; + +MODULE_INIT(CSSetSecure) diff --git a/src/core/cs_set_securefounder.cpp b/src/core/cs_set_securefounder.cpp new file mode 100644 index 000000000..9d4a99d20 --- /dev/null +++ b/src/core/cs_set_securefounder.cpp @@ -0,0 +1,118 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetSecureFounder : public Command +{ + public: + CommandCSSetSecureFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + if (params[1] == "ON") + { + ci->SetFlag(CI_SECUREFOUNDER); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_SECUREFOUNDER); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "SECUREFOUNDER"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET SECUREFOUNDER", CHAN_SET_SECUREFOUNDER_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREFOUNDER); + } +}; + +class CommandCSSASetSecureFounder : public CommandCSSetSecureFounder +{ + public: + CommandCSSASetSecureFounder(const ci::string &cname) : CommandCSSetSecureFounder(cname, "chanserv/saset/securefounder") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET SECUREFOUNDER", CHAN_SASET_SECUREFOUNDER_SYNTAX); + } +}; + +class CSSetSecureFounder : public Module +{ + public: + CSSetSecureFounder(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetSecureFounder("SECUREFOUNDER")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetSecureFounder("SECUREFOUNDER")); + } + + ~CSSetSecureFounder() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("SECUREFOUNDER"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("SECUREFOUNDER"); + } +}; + +MODULE_INIT(CSSetSecureFounder) diff --git a/src/core/cs_set_secureops.cpp b/src/core/cs_set_secureops.cpp new file mode 100644 index 000000000..dc510f71a --- /dev/null +++ b/src/core/cs_set_secureops.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetSecureOps : public Command +{ + public: + CommandCSSetSecureOps(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_SECUREOPS); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_SECUREOPS); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "SECUREOPS"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET SECUREOPS", CHAN_SET_SECUREOPS_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREOPS); + } +}; + +class CommandCSSASetSecureOps : public CommandCSSetSecureOps +{ + public: + CommandCSSASetSecureOps(const ci::string &cname) : CommandCSSetSecureOps(cname, "chanserv/saset/secureops") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET SECUREOPS", CHAN_SASET_SECUREOPS_SYNTAX); + } +}; + +class CSSetSecureOps : public Module +{ + public: + CSSetSecureOps(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetSecureOps("SECUREOPS")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetSecureOps("SECUREOPS")); + } + + ~CSSetSecureOps() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("SECUREOPS"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("SECUREOPS"); + } +}; + +MODULE_INIT(CSSetSecureOps) diff --git a/src/core/cs_set_signkick.cpp b/src/core/cs_set_signkick.cpp new file mode 100644 index 000000000..2e24f8d38 --- /dev/null +++ b/src/core/cs_set_signkick.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetSignKick : public Command +{ + public: + CommandCSSetSignKick(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_SIGNKICK); + ci->UnsetFlag(CI_SIGNKICK_LEVEL); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str()); + } + else if (params[1] == "LEVEL") + { + ci->SetFlag(CI_SIGNKICK_LEVEL); + ci->UnsetFlag(CI_SIGNKICK); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_SIGNKICK); + ci->UnsetFlag(CI_SIGNKICK_LEVEL); + notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "SIGNKICK"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET SIGNKICK", CHAN_SET_SIGNKICK_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SIGNKICK); + } +}; + +class CommandCSSASetSignKick : public CommandCSSetSignKick +{ + public: + CommandCSSASetSignKick(const ci::string &cname) : CommandCSSetSignKick(cname, "chanserv/saset/signkick") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET SIGNKICK", CHAN_SASET_SIGNKICK_SYNTAX); + } +}; + +class CSSetSignKick : public Module +{ + public: + CSSetSignKick(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetSignKick("SIGNKICK")); + } + + ~CSSetSignKick() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("SIGNKICK"); + } +}; + +MODULE_INIT(CSSetSignKick) diff --git a/src/core/cs_set_successor.cpp b/src/core/cs_set_successor.cpp new file mode 100644 index 000000000..3de30631a --- /dev/null +++ b/src/core/cs_set_successor.cpp @@ -0,0 +1,145 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetSuccessor : public Command +{ + public: + CommandCSSetSuccessor(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) + { + notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + NickCore *nc; + + if (params.size() > 1) + { + NickAlias *na = findnick(params[1]); + + if (!na) + { + notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str()); + return MOD_CONT; + } + if (na->HasFlag(NS_FORBIDDEN)) + { + notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick); + return MOD_CONT; + } + if (na->nc == ci->founder) + { + notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, na->nick, ci->name.c_str()); + return MOD_CONT; + } + nc = na->nc; + + } + else + nc = NULL; + + Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from " + << (ci->successor ? ci->successor->display : "none") + << " to " << (nc ? nc->display : "none") << " by " << u->GetMask(); + + ci->successor = nc; + + if (nc) + notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), nc->display); + else + notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str()); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SUCCESSOR); + } +}; + +class CommandCSSASetSuccessor : public CommandCSSetSuccessor +{ + public: + CommandCSSASetSuccessor(const ci::string &cname) : CommandCSSetSuccessor(cname, "chanserv/saset/successor") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASEt", CHAN_SASET_SYNTAX); + } +}; + +class CSSetSuccessor : public Module +{ + public: + CSSetSuccessor(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR")); + } + + ~CSSetSuccessor() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("SUCCESSOR"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("SUCCESSOR"); + } +}; + +MODULE_INIT(CSSetSuccessor) diff --git a/src/core/cs_set_topiclock.cpp b/src/core/cs_set_topiclock.cpp new file mode 100644 index 000000000..14934f551 --- /dev/null +++ b/src/core/cs_set_topiclock.cpp @@ -0,0 +1,112 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetTopicLock : public Command +{ + public: + CommandCSSetTopicLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + ci->SetFlag(CI_TOPICLOCK); + notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_TOPICLOCK); + notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "TOPICLOCK"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_TOPICLOCK_SYNTAX);; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_TOPICLOCK); + } +}; + +class CommandCSSASetTopicLock : public CommandCSSetTopicLock +{ + public: + CommandCSSASetTopicLock(const ci::string &cname) : CommandCSSetTopicLock(cname, "chanserv/saset/topiclock") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_TOPICLOCK_SYNTAX); + } +}; + +class CSSetTopicLock : public Module +{ + public: + CSSetTopicLock(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetTopicLock("TOPICLOCK")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetTopicLock("TOPICLOCK")); + } + + ~CSSetTopicLock() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("TOPICLOCK"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("TOPICLOCK"); + } +}; + +MODULE_INIT(CSSetTopicLock) diff --git a/src/core/cs_set_url.cpp b/src/core/cs_set_url.cpp new file mode 100644 index 000000000..06c49da4f --- /dev/null +++ b/src/core/cs_set_url.cpp @@ -0,0 +1,114 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandCSSetURL : public Command +{ + public: + CommandCSSetURL(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (ci->url) + delete [] ci->url; + if (params.size() > 1) + { + ci->url = sstrdup(params[1].c_str()); + notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), ci->url); + } + else + { + ci->url = NULL; + notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str()); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_URL); + } +}; + +class CommandCSSASetURL : public CommandCSSetURL +{ + public: + CommandCSSASetURL(const ci::string &cname) : CommandCSSetURL(cname, "chanserv/saset/url") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_ChanServ, u, "SASET URL", CHAN_SASET_SYNTAX); + } +}; + +class CSSetURL : public Module +{ + public: + CSSetURL(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetURL("URL")); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->AddSubcommand(new CommandCSSASetURL("URL")); + } + + ~CSSetURL() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("URL"); + + c = FindCommand(ChanServ, "SASET"); + if (c) + c->DelSubcommand("URL"); + } +}; + +MODULE_INIT(CSSetURL) diff --git a/src/core/cs_set_xop.cpp b/src/core/cs_set_xop.cpp new file mode 100644 index 000000000..398cf4c1b --- /dev/null +++ b/src/core/cs_set_xop.cpp @@ -0,0 +1,144 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)])) + +class CommandCSSetXOP : public Command +{ + public: + CommandCSSetXOP(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (!FindModule("cs_xop")) + { + notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, "XOP"); + return MOD_CONT; + } + + ChannelInfo *ci = cs_findchan(params[0]); + assert(ci); + + if (params[1] == "ON") + { + if (!ci->HasFlag(CI_XOP)) + { + ChanAccess *access; + + for (unsigned i = ci->GetAccessCount() - 1; 0 <= i; --i) + { + access = ci->GetAccess(i); + + /* This will probably cause wrong levels to be set, but hey, + * it's better than losing it altogether. + */ + if (access->level == ACCESS_QOP) + access->level = ACCESS_QOP; + else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET)) + access->level = ACCESS_SOP; + else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME)) + access->level = ACCESS_AOP; + else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP) +|| CHECKLEV(CA_HALFOPME))) + access->level = ACCESS_HOP; + else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME)) + access->level = ACCESS_VOP; + else + ci->EraseAccess(i); + } + + reset_levels(ci); + ci->SetFlag(CI_XOP); + } + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str()); + } + else if (params[1] == "OFF") + { + ci->UnsetFlag(CI_XOP); + + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name; + notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str()); + } + else + this->OnSyntaxError(u, "XOP"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SET XOP", CHAN_SET_XOP_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_XOP); + } +}; + +class CommandCSSASetXOP : public CommandCSSetXOP +{ + public: + CommandCSSASetXOP(const ci::string &cname) : CommandCSSetXOP(cname, "chanserv/saset/xop") + { + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SASET"); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_ChanServ, u, "SASET XOP", CHAN_SASET_XOP_SYNTAX); + } +}; + +class CSSetXOP : public Module +{ + public: + CSSetXOP(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->AddSubcommand(new CommandCSSetXOP("XOP")); + } + + ~CSSetXOP() + { + Command *c = FindCommand(ChanServ, "SET"); + if (c) + c->DelSubcommand("XOP"); + } +}; + +MODULE_INIT(CSSetXOP) diff --git a/src/core/cs_status.c b/src/core/cs_status.cpp index 18d175f34..174d1a2d8 100644 --- a/src/core/cs_status.c +++ b/src/core/cs_status.cpp @@ -55,6 +55,11 @@ class CommandCSStatus : public Command { syntax_error(Config.s_ChanServ, u, "STATUS", CHAN_STATUS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_STATUS); + } }; class CSStatus : public Module @@ -65,14 +70,6 @@ class CSStatus : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - - this->AddCommand(CHANSERV, new CommandCSStatus()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_STATUS); } }; diff --git a/src/core/cs_suspend.c b/src/core/cs_suspend.cpp index 39b1f9fd5..6931fb62b 100644 --- a/src/core/cs_suspend.c +++ b/src/core/cs_suspend.cpp @@ -59,7 +59,7 @@ class CommandCSSuspend : public Command if (reason) ci->forbidreason = sstrdup(reason); - if ((c = findchan(ci->name.c_str()))) + if ((c = findchan(ci->name))) { for (CUserList::iterator it = c->users.begin(); it != c->users.end();) { @@ -73,7 +73,7 @@ class CommandCSSuspend : public Command } if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used SUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); + ircdproto->SendGlobops(ChanServ, "\2%s\2 used SUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set SUSPEND for channel " << ci->name; notice_lang(Config.s_ChanServ, u, CHAN_SUSPEND_SUCCEEDED, chan); @@ -98,6 +98,11 @@ class CommandCSSuspend : public Command { syntax_error(Config.s_ChanServ, u, "SUSPEND", Config.ForceForbidReason ? CHAN_SUSPEND_SYNTAX_REASON : CHAN_SUSPEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SUSPEND); + } }; class CommandCSUnSuspend : public Command @@ -143,7 +148,7 @@ class CommandCSUnSuspend : public Command } if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used UNSUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); + ircdproto->SendGlobops(ChanServ, "\2%s\2 used UNSUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str()); Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set UNSUSPEND for channel " << ci->name; notice_lang(Config.s_ChanServ, u, CHAN_UNSUSPEND_SUCCEEDED, chan); @@ -168,6 +173,11 @@ class CommandCSUnSuspend : public Command { syntax_error(Config.s_ChanServ, u, "UNSUSPEND", CHAN_UNSUSPEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNSUSPEND); + } }; class CSSuspend : public Module @@ -179,15 +189,8 @@ class CSSuspend : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSSuspend()); - this->AddCommand(CHANSERV, new CommandCSUnSuspend()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SUSPEND); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNSUSPEND); + this->AddCommand(ChanServ, new CommandCSSuspend()); + this->AddCommand(ChanServ, new CommandCSUnSuspend()); } }; diff --git a/src/core/cs_topic.c b/src/core/cs_topic.cpp index da41e0ac3..9e62fe681 100644 --- a/src/core/cs_topic.c +++ b/src/core/cs_topic.cpp @@ -55,14 +55,14 @@ class CommandCSTopic : public Command if (!check_access(u, ci, CA_TOPIC)) Alog() << Config.s_NickServ << ": " << u->GetMask() << " changed topic of " << c->name << " as services admin."; - if (ircd->join2set && whosends(ci) == findbot(Config.s_ChanServ)) + if (ircd->join2set && whosends(ci) == ChanServ) { - ircdproto->SendJoin(findbot(Config.s_ChanServ), c->name.c_str(), c->creation_time); + ircdproto->SendJoin(ChanServ, c->name.c_str(), c->creation_time); ircdproto->SendMode(NULL, c, "+o %s", Config.s_ChanServ); } ircdproto->SendTopic(whosends(ci), c, u->nick.c_str(), topic ? topic : ""); - if (ircd->join2set && whosends(ci) == findbot(Config.s_ChanServ)) - ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL); + if (ircd->join2set && whosends(ci) == ChanServ) + ircdproto->SendPart(ChanServ, c, NULL); } return MOD_CONT; } @@ -77,6 +77,11 @@ class CommandCSTopic : public Command { syntax_error(Config.s_ChanServ, u, "TOPIC", CHAN_TOPIC_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_TOPIC); + } }; class CSTopic : public Module @@ -88,13 +93,7 @@ class CSTopic : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSTopic()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_TOPIC); + this->AddCommand(ChanServ, new CommandCSTopic()); } }; diff --git a/src/core/cs_unban.c b/src/core/cs_unban.cpp index aa6184fbb..c361032bf 100644 --- a/src/core/cs_unban.c +++ b/src/core/cs_unban.cpp @@ -41,7 +41,7 @@ class CommandCSUnban : public Command u2 = u; if (params.size() > 1) - u2 = finduser(params[1].c_str()); + u2 = finduser(params[1]); if (!u2) { @@ -67,6 +67,11 @@ class CommandCSUnban : public Command { syntax_error(Config.s_ChanServ, u, "UNBAN", CHAN_UNBAN_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNBAN); + } }; class CSUnban : public Module @@ -78,14 +83,7 @@ class CSUnban : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSUnban()); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - - void OnChanServHelp(User *u) - { - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNBAN); + this->AddCommand(ChanServ, new CommandCSUnban()); } }; diff --git a/src/core/cs_xop.c b/src/core/cs_xop.cpp index 702919d8e..4eb8d15f2 100644 --- a/src/core/cs_xop.c +++ b/src/core/cs_xop.cpp @@ -14,10 +14,6 @@ #include "module.h" -int xop_del_callback(User *u, int num, va_list args); -int xop_list_callback(User *u, int num, va_list args); -int xop_list(User *u, int index, ChannelInfo *ci, int *sent_header, int xlev, int xmsg); - enum { XOP_AOP, @@ -114,6 +110,89 @@ int xop_msgs[XOP_TYPES][XOP_MESSAGES] = { CHAN_QOP_CLEAR} }; +class XOPListCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + int level; + int *messages; + bool SentHeader; + public: + XOPListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist, int _level, int *_messages) : NumberList(numlist, false), u(_u), ci(_ci), level(_level), messages(_messages), SentHeader(false) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAccessCount()) + return; + + ChanAccess *access = ci->GetAccess(Number - 1); + + if (level != access->level) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, messages[XOP_LIST_HEADER], ci->name.c_str()); + } + + DoList(u, ci, access, Number - 1, level, messages); + } + + static void DoList(User *u, ChannelInfo *ci, ChanAccess *access, unsigned index, int level, int *messages) + { + notice_lang(Config.s_ChanServ, u, CHAN_XOP_LIST_FORMAT, index, access->nc->display); + } +}; + +class XOPDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + int *messages; + unsigned Deleted; + std::string Nicks; + public: + XOPDelCallback(User *_u, ChannelInfo *_ci, int *_messages, const std::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), messages(_messages), Deleted(0) + { + } + + ~XOPDelCallback() + { + if (!Deleted) + notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str()); + else + { + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of users " << Nicks << " on " << ci->name; + + if (Deleted == 1) + notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_ONE], ci->name.c_str()); + else + notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_SEVERAL], Deleted, ci->name.c_str()); + } + } + + void HandleNumber(unsigned Number) + { + if (Number > ci->GetAccessCount()) + return; + + ChanAccess *access = ci->GetAccess(Number - 1); + + ++Deleted; + if (!Nicks.empty()) + Nicks += ", " + std::string(access->nc->display); + else + Nicks = access->nc->display; + + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc)); + + ci->EraseAccess(Number - 1); + } +}; + class XOPBase : public Command { private: @@ -178,8 +257,7 @@ class XOPBase : public Command if (!change) { - std::string usernick = u->nick; - ci->AddAccess(nc, level, usernick); + ci->AddAccess(nc, level, u->nick); } else { @@ -194,12 +272,12 @@ class XOPBase : public Command if (!change) { - FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, na, level)); + FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level)); notice_lang(Config.s_ChanServ, u, messages[XOP_ADDED], nc->display, ci->name.c_str()); } else { - FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na, level)); + FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level)); notice_lang(Config.s_ChanServ, u, messages[XOP_MOVED], nc->display, ci->name.c_str()); } @@ -211,8 +289,6 @@ class XOPBase : public Command const char *nick = params.size() > 2 ? params[2].c_str() : NULL; ChanAccess *access; - int deleted; - if (!nick) { this->OnSyntaxError(u, "DEL"); @@ -241,26 +317,7 @@ class XOPBase : public Command /* Special case: is it a number/list? Only do search if it isn't. */ if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick)) - { - int count, last = -1, perm = 0; - deleted = process_numlist(nick, &count, xop_del_callback, u, ci, &last, &perm, ulev, level); - if (!deleted) - { - if (perm) - notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); - else if (count == 1) - { - last = atoi(nick); - notice_lang(Config.s_ChanServ, u, messages[XOP_NO_SUCH_ENTRY], last, ci->name.c_str()); - } - else - notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str()); - } - else if (deleted == 1) - notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_ONE], ci->name.c_str()); - else - notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_SEVERAL], deleted, ci->name.c_str()); - } + (new XOPDelCallback(u, ci, messages, nick))->Process(); else { NickAlias *na = findnick(nick); @@ -270,9 +327,17 @@ class XOPBase : public Command return MOD_CONT; } NickCore *nc = na->nc; - access = ci->GetAccess(nc, level); - if (!access) + unsigned i; + for (i = 0; i < ci->GetAccessCount(); ++i) + { + access = ci->GetAccess(nc, level); + + if (access->nc == nc) + break; + } + + if (i == ci->GetAccessCount()) { notice_lang(Config.s_ChanServ, u, messages[XOP_NOT_FOUND], nick, ci->name.c_str()); return MOD_CONT; @@ -280,34 +345,25 @@ class XOPBase : public Command if (ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) { - deleted = 0; notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); } else { + Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user " << access->nc->display << " on " << ci->name; + notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED], access->nc->display, ci->name.c_str()); - access->nc = NULL; - access->in_use = 0; FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); - deleted = 1; + ci->EraseAccess(i); } } - if (deleted) - { - /* If the patch provided in bug #706 is applied, this should be placed - * before sending the events! */ - /* We'll free the access entries no longer in use... */ - ci->CleanAccess(); - } return MOD_CONT; } CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms, ChannelInfo *ci, int level, int *messages) { - int sent_header = 0; const char *nick = params.size() > 2 ? params[2].c_str() : NULL; if (!get_access(u, ci) && !u->Account()->HasCommand("chanserv/access/list")) @@ -323,19 +379,30 @@ class XOPBase : public Command } if (nick && strspn(nick, "1234567890,-") == strlen(nick)) - process_numlist(nick, NULL, xop_list_callback, u, ci, &sent_header, level, messages[XOP_LIST_HEADER]); + (new XOPListCallback(u, ci, nick, level, messages))->Process(); else { + bool SentHeader = false; + for (unsigned i = 0; i < ci->GetAccessCount(); ++i) { ChanAccess *access = ci->GetAccess(i); + if (nick && access->nc && !Anope::Match(access->nc->display, nick, false)) continue; - xop_list(u, i, ci, &sent_header, level, messages[XOP_LIST_HEADER]); + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_ChanServ, u, messages[XOP_LIST_HEADER], ci->name.c_str()); + } + + XOPListCallback::DoList(u, ci, access, i, level, messages); } + + if (!SentHeader) + notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str()); } - if (!sent_header) - notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str()); return MOD_CONT; } @@ -354,7 +421,7 @@ class XOPBase : public Command return MOD_CONT; } - if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify")) + if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify")) { notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); return MOD_CONT; @@ -363,7 +430,7 @@ class XOPBase : public Command for (unsigned i = ci->GetAccessCount(); i > 0; --i) { ChanAccess *access = ci->GetAccess(i - 1); - if (access->in_use && access->level == level) + if (access->level == level) ci->EraseAccess(i - 1); } @@ -396,7 +463,7 @@ class XOPBase : public Command return MOD_CONT; } public: - XOPBase(const std::string &command) : Command(command, 2, 3) + XOPBase(const ci::string &command) : Command(command, 2, 3) { } @@ -409,6 +476,8 @@ class XOPBase : public Command virtual bool OnHelp(User *u, const ci::string &subcommand) = 0; virtual void OnSyntaxError(User *u, const ci::string &subcommand) = 0; + + virtual void OnServHelp(User *u) = 0; }; class CommandCSQOP : public XOPBase @@ -433,6 +502,11 @@ class CommandCSQOP : public XOPBase { syntax_error(Config.s_ChanServ, u, "QOP", CHAN_QOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_QOP); + } }; class CommandCSAOP : public XOPBase @@ -457,6 +531,11 @@ class CommandCSAOP : public XOPBase { syntax_error(Config.s_ChanServ, u, "AOP", CHAN_AOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AOP); + } }; class CommandCSHOP : public XOPBase @@ -481,6 +560,11 @@ class CommandCSHOP : public XOPBase { syntax_error(Config.s_ChanServ, u, "HOP", CHAN_HOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HOP); + } }; class CommandCSSOP : public XOPBase @@ -505,6 +589,11 @@ class CommandCSSOP : public XOPBase { syntax_error(Config.s_ChanServ, u, "SOP", CHAN_SOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SOP); + } }; class CommandCSVOP : public XOPBase @@ -529,6 +618,11 @@ class CommandCSVOP : public XOPBase { syntax_error(Config.s_ChanServ, u, "VOP", CHAN_VOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOP); + } }; class CSXOP : public Module @@ -540,111 +634,32 @@ class CSXOP : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(CHANSERV, new CommandCSSOP()); - this->AddCommand(CHANSERV, new CommandCSAOP()); - this->AddCommand(CHANSERV, new CommandCSVOP()); + this->AddCommand(ChanServ, new CommandCSSOP()); + this->AddCommand(ChanServ, new CommandCSAOP()); + this->AddCommand(ChanServ, new CommandCSVOP()); - if (serv_uplink && is_sync(serv_uplink)) - OnUplinkSync(); + if (Me && Me->IsSynced()) + OnUplinkSync(NULL); Implementation i[] = { - I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp + I_OnUplinkSync, I_OnServerDisconnect }; - ModuleManager::Attach(i, this, 3); + ModuleManager::Attach(i, this, 2); } - void OnUplinkSync() + void OnUplinkSync(Server *) { if (ModeManager::FindChannelModeByName(CMODE_OWNER)) - this->AddCommand(CHANSERV, new CommandCSQOP()); + this->AddCommand(ChanServ, new CommandCSQOP()); if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) - this->AddCommand(CHANSERV, new CommandCSHOP()); + this->AddCommand(ChanServ, new CommandCSHOP()); } void OnServerDisconnect() { - this->DelCommand(CHANSERV, "QOP"); - this->DelCommand(CHANSERV, "HOP"); - } - - void OnChanServHelp(User *u) - { - if (ModeManager::FindChannelModeByName(CMODE_OWNER)) - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_QOP); - if (ModeManager::FindChannelModeByName(CMODE_PROTECT)) - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SOP); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AOP); - if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HOP); - notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOP); + this->DelCommand(ChanServ, FindCommand(ChanServ, "QOP")); + this->DelCommand(ChanServ, FindCommand(ChanServ, "HOP")); } }; -/* `last' is set to the last index this routine was called with - * `perm' is incremented whenever a permission-denied error occurs - */ -int xop_del(User *u, ChannelInfo *ci, ChanAccess *access, int *perm, int uacc, int xlev) -{ - if (!access->in_use || access->level != xlev) - return 0; - if (uacc <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) - { - ++(*perm); - return 0; - } - NickCore *nc = access->nc; - access->nc = NULL; - access->in_use = 0; - - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, nc)); - - return 1; -} - -int xop_del_callback(User *u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *last = va_arg(args, int *); - int *perm = va_arg(args, int *); - int uacc = va_arg(args, int); - int xlev = va_arg(args, int); - - if (num < 1 || num > ci->GetAccessCount()) - return 0; - *last = num; - - return xop_del(u, ci, ci->GetAccess(num - 1), perm, uacc, xlev); -} - - -int xop_list(User *u, int index, ChannelInfo *ci, int *sent_header, int xlev, int xmsg) -{ - ChanAccess *access = ci->GetAccess(index); - - if (!access->in_use || access->level != xlev) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_ChanServ, u, xmsg, ci->name.c_str()); - *sent_header = 1; - } - - notice_lang(Config.s_ChanServ, u, CHAN_XOP_LIST_FORMAT, index + 1, access->nc->display); - return 1; -} - -int xop_list_callback(User *u, int num, va_list args) -{ - ChannelInfo *ci = va_arg(args, ChannelInfo *); - int *sent_header = va_arg(args, int *); - int xlev = va_arg(args, int); - int xmsg = va_arg(args, int); - - if (num < 1 || num > ci->GetAccessCount()) - return 0; - - return xop_list(u, num - 1, ci, sent_header, xlev, xmsg); -} - MODULE_INIT(CSXOP) diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp index 65f936650..98e055ee8 100644 --- a/src/core/db_plain.cpp +++ b/src/core/db_plain.cpp @@ -24,6 +24,7 @@ enum MDType MD_NONE, MD_NC, MD_NA, + MD_NR, MD_BI, MD_CH }; @@ -39,7 +40,6 @@ static const char endl = '\n'; */ static void ReadDatabase(Module *m = NULL) { - std::string buf; EventReturn MOD_RESULT; MDType Type = MD_NONE; @@ -53,9 +53,11 @@ static void ReadDatabase(Module *m = NULL) NickCore *nc = NULL; NickAlias *na = NULL; + NickRequest *nr = NULL; BotInfo *bi = NULL; ChannelInfo *ci = NULL; + std::string buf; while (std::getline(db, buf)) { if (buf.empty()) @@ -87,19 +89,23 @@ static void ReadDatabase(Module *m = NULL) if (MOD_RESULT == EVENT_STOP) continue; - std::string mdbuf; if (!params.empty()) { if (params[0] == "NC") { - nc = findcore(params[1].c_str()); + nc = findcore(params[1]); Type = MD_NC; } else if (params[0] == "NA") { - na = findnick(params[2].c_str()); + na = findnick(params[2]); Type = MD_NA; } + else if (params[0] == "NR") + { + nr = findrequestnick(params[1]); + Type = MD_NR; + } else if (params[0] == "BI") { bi = findbot(params[1]); @@ -148,6 +154,22 @@ static void ReadDatabase(Module *m = NULL) Alog() << "[db_plain]: " << ex.GetReason(); } } + else if (Type == MD_NR && nr) + { + try + { + if (m) + m->OnDatabaseReadMetadata(nr, key, params); + else + { + FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(nr, key, params)); + } + } + catch (DatabaseException& ex) + { + Alog() << "[db_plain]: " << ex.GetReason(); + } + } else if (Type == MD_BI && bi) { try @@ -198,12 +220,6 @@ struct LangInfo int LanguageId; }; -struct ChannelModeInfo -{ - std::string Name; - ChannelModeName Value; -}; - struct ChannelFlagInfo { std::string Name; @@ -245,42 +261,6 @@ LangInfo LangInfos[] = { {"", -1} }; -ChannelModeInfo ChannelModes[] = { - {"CMODE_BLOCKCOLOR", CMODE_BLOCKCOLOR}, - {"CMODE_FLOOD", CMODE_FLOOD}, - {"CMODE_INVITE", CMODE_INVITE}, - {"CMODE_KEY", CMODE_KEY}, - {"CMODE_LIMIT", CMODE_LIMIT}, - {"CMODE_MODERATED", CMODE_MODERATED}, - {"CMODE_NOEXTERNAL", CMODE_NOEXTERNAL}, - {"CMODE_PRIVATE", CMODE_PRIVATE}, - {"CMODE_REGISTERED", CMODE_REGISTERED}, - {"CMODE_SECRET", CMODE_SECRET}, - {"CMODE_TOPIC", CMODE_TOPIC}, - {"CMODE_AUDITORIUM", CMODE_AUDITORIUM}, - {"CMODE_SSL", CMODE_SSL}, - {"CMODE_ADMINONLY", CMODE_ADMINONLY}, - {"CMODE_NOCTCP", CMODE_NOCTCP}, - {"CMODE_FILTER", CMODE_FILTER}, - {"CMODE_NOKNOCK", CMODE_NOKNOCK}, - {"CMODE_REDIRECT", CMODE_REDIRECT}, - {"CMODE_REGMODERATED", CMODE_REGMODERATED}, - {"CMODE_NONICK", CMODE_NONICK}, - {"CMODE_OPERONLY", CMODE_OPERONLY}, - {"CMODE_NONICK", CMODE_NONICK}, - {"CMODE_REGISTEREDONLY", CMODE_REGISTEREDONLY}, - {"CMODE_STRIPCOLOR", CMODE_STRIPCOLOR}, - {"CMODE_NONOTICE", CMODE_NONOTICE}, - {"CMODE_NOINVITE", CMODE_NOINVITE}, - {"CMODE_ALLINVITE", CMODE_ALLINVITE}, - {"CMODE_BLOCKCAPS", CMODE_BLOCKCAPS}, - {"CMODE_PERM", CMODE_PERM}, - {"CMODE_NICKFLOOD", CMODE_NICKFLOOD}, - {"CMODE_JOINFLOOD", CMODE_JOINFLOOD}, - {"CMODE_NOREJOIN", CMODE_NOREJOIN}, - {"", static_cast<ChannelModeName>(-1)} -}; - ChannelFlagInfo ChannelInfoFlags[] = { {"KEEPTOPIC", CI_KEEPTOPIC}, {"SECUREOPS", CI_SECUREOPS}, @@ -410,7 +390,7 @@ static void LoadNickCore(const std::vector<std::string> ¶ms) static void LoadNickAlias(const std::vector<std::string> ¶ms) { - NickCore *nc = findcore(params[0].c_str()); + NickCore *nc = findcore(params[0]); if (!nc) { Alog() << "[db_plain]: Unable to find core " << params[0]; @@ -442,11 +422,11 @@ static void LoadBotInfo(const std::vector<std::string> ¶ms) BotInfo *bi = findbot(params[0]); if (!bi) bi = new BotInfo(params[0]); - bi->user = sstrdup(params[1].c_str()); - bi->host = sstrdup(params[2].c_str()); + bi->user = params[1]; + bi->host = params[2]; bi->created = atol(params[3].c_str()); bi->chancount = atol(params[4].c_str()); - bi->real = sstrdup(params[5].c_str()); + bi->real = params[5]; Alog(LOG_DEBUG_2) << "[db_plain]: Loaded botinfo for " << bi->nick; } @@ -478,31 +458,42 @@ static void LoadOperInfo(const std::vector<std::string> ¶ms) maxusercnt = atol(params[1].c_str()); maxusertime = strtol(params[2].c_str(), NULL, 10); } - else if (params[0] == "SGLINE" || params[0] == "SQLINE" || params[0] == "SZLINE") + else if (params[0] == "SNLINE" || params[0] == "SQLINE" || params[0] == "SZLINE") { - SXLine *sx = new SXLine; - sx->mask = sstrdup(params[1].c_str()); - sx->by = sstrdup(params[2].c_str()); - sx->seton = atol(params[3].c_str()); - sx->expires = atol(params[4].c_str()); - sx->reason = sstrdup(params[5].c_str()); - if (params[0] == "SGLINE") - slist_add(&sglines, sx); - else if (params[0] == "SQLINE") - slist_add(&sqlines, sx); - else if (params[0] == "SZLINE") - slist_add(&szlines, sx); + ci::string mask = params[1].c_str(); + ci::string by = params[2].c_str(); + time_t seton = atol(params[3].c_str()); + time_t expires = atol(params[4].c_str()); + std::string reason = params[5]; + + XLine *x = NULL; + if (params[0] == "SNLINE" && SNLine) + x = SNLine->Add(NULL, NULL, mask, expires, reason); + else if (params[0] == "SQLINE" && SQLine) + x = SQLine->Add(NULL, NULL, mask, expires, reason); + else if (params[0] == "SZLINE" && SZLine) + x = SZLine->Add(NULL, NULL, mask, expires, reason); + if (x) + { + x->By = by; + x->Created = seton; + } } - else if (params[0] == "AKILL") + else if (params[0] == "AKILL" && SGLine) { - Akill *ak = new Akill; - ak->user = sstrdup(params[1].c_str()); - ak->host = sstrdup(params[2].c_str()); - ak->by = sstrdup(params[3].c_str()); - ak->seton = atol(params[4].c_str()); - ak->expires = atol(params[5].c_str()); - ak->reason = sstrdup(params[6].c_str()); - slist_add(&akills, ak); + ci::string user = params[1].c_str(); + ci::string host = params[2].c_str(); + ci::string by = params[3].c_str(); + time_t seton = atol(params[4].c_str()); + time_t expires = atol(params[5].c_str()); + std::string reason = params[6]; + + XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason); + if (x) + { + x->By = by; + x->Created = seton; + } } else if (params[0] == "EXCEPTION") { @@ -556,8 +547,7 @@ class DBPlain : public Module void BackupDatabase() { /* Do not backup a database that doesn't exist */ - struct stat DBInfo; - if (stat(DatabaseFile.c_str(), &DBInfo)) + if (!IsFile(DatabaseFile)) { return; } @@ -572,7 +562,7 @@ class DBPlain : public Module snprintf(newname, DatabaseFile.length() + 30, "backups/%s.%d%d%d", DatabaseFile.c_str(), tm->tm_year, tm->tm_mon, tm->tm_mday); /* Backup already exists */ - if (!stat(newname, &DBInfo)) + if (IsFile(newname)) { delete [] newname; return; @@ -581,7 +571,7 @@ class DBPlain : public Module Alog(LOG_DEBUG) << "db_plain: Attemping to rename " << DatabaseFile << " to " << newname; if (rename(DatabaseFile.c_str(), newname) != 0) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "Unable to backup database!"); + ircdproto->SendGlobops(OperServ, "Unable to backup database!"); Alog() << "Unable to back up database!"; if (!Config.NoBackupOkay) @@ -719,20 +709,6 @@ class DBPlain : public Module { if (params[j] == "PRIVATE") bi->SetFlag(BI_PRIVATE); - else if (params[j] == "CHANSERV") - bi->SetFlag(BI_CHANSERV); - else if (params[j] == "BOTSERV") - bi->SetFlag(BI_BOTSERV); - else if (params[j] == "HOSTSERV") - bi->SetFlag(BI_HOSTSERV); - else if (params[j] == "OPERSERV") - bi->SetFlag(BI_OPERSERV); - else if (params[j] == "MEMOSERV") - bi->SetFlag(BI_MEMOSERV); - else if (params[j] == "NICKSERV") - bi->SetFlag(BI_NICKSERV); - else if (params[j] == "GLOBAL") - bi->SetFlag(BI_GLOBAL); } } @@ -741,11 +717,9 @@ class DBPlain : public Module EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const std::string &key, const std::vector<std::string> ¶ms) { - int i; - if (key == "FOUNDER") { - ci->founder = findcore(params[0].c_str()); + ci->founder = findcore(params[0]); if (!ci->founder) { std::stringstream reason; @@ -754,18 +728,18 @@ class DBPlain : public Module } } else if (key == "SUCCESSOR") - ci->successor = findcore(params[0].c_str()); + ci->successor = findcore(params[0]); else if (key == "LEVELS") { for (unsigned j = 0; j < params.size(); ++j, ++j) - for (i = 0; ChannelLevels[i].Level != -1; ++i) + for (int i = 0; ChannelLevels[i].Level != -1; ++i) if (ChannelLevels[i].Name == params[j]) ci->levels[ChannelLevels[i].Level] = atoi(params[j + 1].c_str()); } else if (key == "FLAGS") { for (unsigned j = 0; j < params.size(); ++j) - for (i = 0; ChannelInfoFlags[i].Flag != -1; ++i) + for (int i = 0; ChannelInfoFlags[i].Flag != -1; ++i) if (ChannelInfoFlags[i].Name == params[j]) ci->SetFlag(ChannelInfoFlags[i].Flag); } @@ -788,7 +762,7 @@ class DBPlain : public Module } else if (key == "ACCESS") { - NickCore *nc = findcore(params[0].c_str()); + NickCore *nc = findcore(params[0]); if (!nc) { std::stringstream reason; @@ -807,7 +781,7 @@ class DBPlain : public Module NickCore *nc = NULL; if (Nick) { - nc = findcore(params[2].c_str()); + nc = findcore(params[2]); if (!nc) { std::stringstream reason; @@ -830,17 +804,20 @@ class DBPlain : public Module { bool Set = key == "MLOCK_ON" ? true : false; - for (unsigned j = 0; j < params.size(); ++j) - for (i = 0; ChannelModes[i].Value != -1; ++i) - if (ChannelModes[i].Name == params[j]) - ci->SetMLock(ChannelModes[i].Value, Set); + /* For now store mlock in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */ + ci->Extend(Set ? "db_mlock_modes_on" : "db_mlock_modes_off", new ExtensibleItemRegular<std::vector<std::string> >(params)); } else if (key == "MLP") { + std::vector<std::pair<std::string, std::string> > mlp; + for (unsigned j = 0; j < params.size(); ++j, ++j) - for (i = 0; ChannelModes[i].Value != -1; ++i) - if (ChannelModes[i].Name == params[j]) - ci->SetMLock(ChannelModes[i].Value, true, params[j + 1]); + { + mlp.push_back(std::make_pair(params[j], params[j + 1])); + } + + /* For now store mlocked modes in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */ + ci->Extend("db_mlp", new ExtensibleItemRegular<std::vector<std::pair<std::string, std::string> > >(mlp)); } else if (key == "MI") { @@ -869,7 +846,7 @@ class DBPlain : public Module else if (params[0] == "FLAGS") { for (unsigned j = 1; j < params.size(); ++j) - for (i = 0; BotFlags[i].Flag != -1; ++i) + for (int i = 0; BotFlags[i].Flag != -1; ++i) if (BotFlags[i].Name == params[j]) ci->botflags.SetFlag(BotFlags[i].Flag); } @@ -937,282 +914,295 @@ class DBPlain : public Module db << "VER 1" << endl; - int i, j; - unsigned k; - - for (i = 0; i < 1024; ++i) + for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it) { - for (NickRequest *nr = nrlists[i]; nr; nr = nr->next) - { - db << "NR " << nr->nick << " " << nr->passcode << " " << nr->password << " " << nr->email << " " << nr->requested << endl; - } + NickRequest *nr = it->second; + + db << "NR " << nr->nick << " " << nr->passcode << " " << nr->password << " " << nr->email << " " << nr->requested << endl; + + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nr)); } - NickCore *nc; - for (i = 0; i < 1024; ++i) + for (nickcore_map::const_iterator nit = NickCoreList.begin(); nit != NickCoreList.end(); ++nit) { - for (nc = nclists[i]; nc; nc = nc->next) + NickCore *nc = nit->second; + + if (nc->HasFlag(NI_FORBIDDEN)) { - if (nc->HasFlag(NI_FORBIDDEN)) - { - db << "NC " << nc->display << endl; - db << "MD FLAGS FORBIDDEN" << endl; - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc)); - continue; - } - else - { - db << "NC " << nc->display << " " << nc->pass << " "; - } - for (j = 0; LangInfos[j].LanguageId != -1; ++j) - if (nc->language == LangInfos[j].LanguageId) - db << LangInfos[j].Name; - db << " " << nc->memos.memomax << " " << nc->channelcount << endl; - - if (nc->email) - db << "MD EMAIL " << nc->email << endl; - if (nc->greet) - db << "MD GREET :" << nc->greet << endl; - if (nc->icq) - db << "MD ICQ :" << nc->icq << endl; - if (nc->url) - db << "MD URL :" << nc->url << endl; - if (!nc->access.empty()) - { - for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it) - db << "MD ACCESS " << *it << endl; - } - if (nc->FlagCount()) - { - db << "MD FLAGS"; - for (j = 0; NickCoreFlags[j].Flag != -1; ++j) - if (nc->HasFlag(NickCoreFlags[j].Flag)) - db << " " << NickCoreFlags[j].Name; - db << endl; - } - if (!nc->memos.memos.empty()) + db << "NC " << nc->display << endl; + db << "MD FLAGS FORBIDDEN" << endl; + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc)); + continue; + } + else + { + db << "NC " << nc->display << " " << nc->pass << " "; + } + for (int j = 0; LangInfos[j].LanguageId != -1; ++j) + if (nc->language == LangInfos[j].LanguageId) + db << LangInfos[j].Name; + db << " " << nc->memos.memomax << " " << nc->channelcount << endl; + + if (nc->email) + db << "MD EMAIL " << nc->email << endl; + if (nc->greet) + db << "MD GREET :" << nc->greet << endl; + if (nc->icq) + db << "MD ICQ :" << nc->icq << endl; + if (nc->url) + db << "MD URL :" << nc->url << endl; + if (!nc->access.empty()) + { + for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it) + db << "MD ACCESS " << *it << endl; + } + if (nc->FlagCount()) + { + db << "MD FLAGS"; + for (int j = 0; NickCoreFlags[j].Flag != -1; ++j) + if (nc->HasFlag(NickCoreFlags[j].Flag)) + db << " " << NickCoreFlags[j].Name; + db << endl; + } + if (!nc->memos.memos.empty()) + { + MemoInfo *mi = &nc->memos; + for (unsigned k = 0; k < mi->memos.size(); ++k) { - MemoInfo *mi = &nc->memos; - for (k = 0; k < mi->memos.size(); ++k) - { - db << "MD MI " << mi->memos[k]->number << " " << mi->memos[k]->time << " " << mi->memos[k]->sender; - if (mi->memos[k]->HasFlag(MF_UNREAD)) - db << " UNREAD"; - if (mi->memos[k]->HasFlag(MF_RECEIPT)) - db << " RECEIPT"; - if (mi->memos[k]->HasFlag(MF_NOTIFYS)) - db << " NOTIFYS"; - db << " :" << mi->memos[k]->text << endl; - } + db << "MD MI " << mi->memos[k]->number << " " << mi->memos[k]->time << " " << mi->memos[k]->sender; + if (mi->memos[k]->HasFlag(MF_UNREAD)) + db << " UNREAD"; + if (mi->memos[k]->HasFlag(MF_RECEIPT)) + db << " RECEIPT"; + if (mi->memos[k]->HasFlag(MF_NOTIFYS)) + db << " NOTIFYS"; + db << " :" << mi->memos[k]->text << endl; } - - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc)); - } + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc)); + } - NickAlias *na; - for (i = 0; i < 1024; ++i) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (na = nalists[i]; na; na = na->next) + NickAlias *na = it->second; + + db << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl; + if (na->last_usermask) + db << "MD LAST_USERMASK " << na->last_usermask << endl; + if (na->last_realname) + db << "MD LAST_REALNAME :" << na->last_realname << endl; + if (na->last_quit) + db << "MD LAST_QUIT :" << na->last_quit << endl; + if (na->HasFlag(NS_FORBIDDEN) || na->HasFlag(NS_NO_EXPIRE)) { - db << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl; - if (na->last_usermask) - db << "MD LAST_USERMASK " << na->last_usermask << endl; - if (na->last_realname) - db << "MD LAST_REALNAME :" << na->last_realname << endl; - if (na->last_quit) - db << "MD LAST_QUIT :" << na->last_quit << endl; - if (na->HasFlag(NS_FORBIDDEN) || na->HasFlag(NS_NO_EXPIRE)) - { - db << "MD FLAGS" << (na->HasFlag(NS_FORBIDDEN) ? " FORBIDDEN" : "") << (na->HasFlag(NS_NO_EXPIRE) ? " NOEXPIRE " : "") << endl; - } - if (na->hostinfo.HasVhost()) - { - db << "MD VHOST " << na->hostinfo.GetCreator() << " " << na->hostinfo.GetTime() << " " << na->hostinfo.GetHost() << " :" << na->hostinfo.GetIdent() << endl; - } - - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, na)); + db << "MD FLAGS" << (na->HasFlag(NS_FORBIDDEN) ? " FORBIDDEN" : "") << (na->HasFlag(NS_NO_EXPIRE) ? " NOEXPIRE " : "") << endl; + } + if (na->hostinfo.HasVhost()) + { + db << "MD VHOST " << na->hostinfo.GetCreator() << " " << na->hostinfo.GetTime() << " " << na->hostinfo.GetHost() << " :" << na->hostinfo.GetIdent() << endl; } + + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, na)); } - BotInfo *bi; - for (i = 0; i < 256; ++i) + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) { - for (bi = botlists[i]; bi; bi = bi->next) + BotInfo *bi = it->second; + + db << "BI " << bi->nick << " " << bi->user << " " << bi->host << " " << bi->created << " " << bi->chancount << " :" << bi->real << endl; + if (bi->FlagCount()) { - db << "BI " << bi->nick << " " << bi->user << " " << bi->host << " " << bi->created << " " << bi->chancount << " :" << bi->real << endl; - if (bi->FlagCount()) - { - db << "MD FLAGS"; - if (bi->HasFlag(BI_PRIVATE)) - db << " PRIVATE"; - if (bi->HasFlag(BI_CHANSERV)) - db << " CHANSERV"; - else if (bi->HasFlag(BI_BOTSERV)) - db << " BOTSERV"; - else if (bi->HasFlag(BI_HOSTSERV)) - db << " HOSTSERV"; - else if (bi->HasFlag(BI_OPERSERV)) - db << " OPERSERV"; - else if (bi->HasFlag(BI_MEMOSERV)) - db << " MEMOSERV"; - else if (bi->HasFlag(BI_NICKSERV)) - db << " NICKSERV"; - else if (bi->HasFlag(BI_GLOBAL)) - db << " GLOBAL"; - db << endl; - } - - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, bi)); + db << "MD FLAGS"; + if (bi->HasFlag(BI_PRIVATE)) + db << " PRIVATE"; + db << endl; } } - ChannelInfo *ci; - for (i = 0; i < 256; ++i) + for (registered_channel_map::const_iterator cit = RegisteredChannelList.begin(); cit != RegisteredChannelList.end(); ++cit) { - for (ci = chanlists[i]; ci; ci = ci->next) + ChannelInfo *ci = cit->second; + + db << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used; + db << " " << ci->bantype << " " << ci->memos.memomax << endl; + if (ci->founder) + db << "MD FOUNDER " << ci->founder->display << endl; + if (ci->successor) + db << "MD SUCCESSOR " << ci->successor->display << endl; + if (ci->desc) + db << "MD DESC :" << ci->desc << endl; + if (ci->url) + db << "MD URL :" << ci->url << endl; + if (ci->email) + db << "MD EMAIL :" << ci->email << endl; + if (ci->last_topic) + db << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl; + db << "MD LEVELS"; + for (int j = 0; ChannelLevels[j].Level != -1; ++j) + db << " " << ChannelLevels[j].Name << " " << ci->levels[ChannelLevels[j].Level]; + db << endl; + if (ci->FlagCount()) { - db << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used; - db << " " << ci->bantype << " " << ci->memos.memomax << endl; - if (ci->founder) - db << "MD FOUNDER " << ci->founder->display << endl; - if (ci->successor) - db << "MD SUCCESSOR " << ci->successor->display << endl; - if (ci->desc) - db << "MD DESC :" << ci->desc << endl; - if (ci->url) - db << "MD URL :" << ci->url << endl; - if (ci->email) - db << "MD EMAIL :" << ci->email << endl; - if (ci->last_topic) - db << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl; - db << "MD LEVELS"; - for (j = 0; ChannelLevels[j].Level != -1; ++j) - db << " " << ChannelLevels[j].Name << " " << ci->levels[ChannelLevels[j].Level]; + db << "MD FLAGS"; + for (int j = 0; ChannelInfoFlags[j].Flag != -1; ++j) + if (ci->HasFlag(ChannelInfoFlags[j].Flag)) + db << " " << ChannelInfoFlags[j].Name; db << endl; - if (ci->FlagCount()) - { - db << "MD FLAGS"; - for (j = 0; ChannelInfoFlags[j].Flag != -1; ++j) - if (ci->HasFlag(ChannelInfoFlags[j].Flag)) - db << " " << ChannelInfoFlags[j].Name; - db << endl; - if (ci->HasFlag(CI_FORBIDDEN)) - db << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl; - } - for (k = 0; k < ci->GetAccessCount(); ++k) - if (ci->GetAccess(k)->in_use) - db << "MD ACCESS " << ci->GetAccess(k)->nc->display << " " << ci->GetAccess(k)->level << " " - << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl; - for (k = 0; k < ci->GetAkickCount(); ++k) - { - db << "MD AKICK " - << (ci->GetAkick(k)->HasFlag(AK_STUCK) ? "STUCK " : "UNSTUCK ") - << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ") - << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask) - << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime - << " " << ci->last_used << " :"; - if (!ci->GetAkick(k)->reason.empty()) - db << ci->GetAkick(k)->reason; - db << endl; - } - if (ci->GetMLockCount(true)) + if (ci->HasFlag(CI_FORBIDDEN)) + db << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl; + } + for (unsigned k = 0; k < ci->GetAccessCount(); ++k) + db << "MD ACCESS " << ci->GetAccess(k)->nc->display << " " << ci->GetAccess(k)->level << " " + << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl; + for (unsigned k = 0; k < ci->GetAkickCount(); ++k) + { + db << "MD AKICK " + << (ci->GetAkick(k)->HasFlag(AK_STUCK) ? "STUCK " : "UNSTUCK ") + << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ") + << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask) + << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime + << " " << ci->last_used << " :"; + if (!ci->GetAkick(k)->reason.empty()) + db << ci->GetAkick(k)->reason; + db << endl; + } + if (ci->GetMLockCount(true)) + { + db << "MD MLOCK_ON"; + for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it) { - db << "MD MLOCK_ON"; - for (j = 0; ChannelModes[j].Value != -1; ++j) - if (ci->HasMLock(ChannelModes[j].Value, true)) - db << " " << ChannelModes[j].Name; - db << endl; + if ((*it)->Class == MC_CHANNEL) + { + ChannelMode *cm = dynamic_cast<ChannelMode *>(*it); + + if (ci->HasMLock(cm->Name, true)) + { + db << " " << cm->NameAsString; + } + } } - if (ci->GetMLockCount(false)) + db << endl; + } + if (ci->GetMLockCount(false)) + { + db << "MD MLOCK_OFF"; + for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it) { - db << "MD MLOCK_OFF"; - for (j = 0; ChannelModes[j].Value != -1; ++j) - if (ci->HasMLock(ChannelModes[j].Value, false)) - db << " " << ChannelModes[j].Name; - db << endl; + if ((*it)->Class == MC_CHANNEL) + { + ChannelMode *cm = dynamic_cast<ChannelMode *>(*it); + + if (ci->HasMLock(cm->Name, false)) + { + db << " " << cm->NameAsString; + } + } } - std::string Param; - for (j = 0; ChannelModes[j].Value != -1; ++j) - if (ci->GetParam(ChannelModes[j].Value, Param)) - db << "MD MLP " << ChannelModes[j].Name << " " << Param << endl; - if (!ci->memos.memos.empty()) + db << endl; + } + std::string Param; + for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it) + { + if ((*it)->Class == MC_CHANNEL) { - MemoInfo *memos = &ci->memos; + ChannelMode *cm = dynamic_cast<ChannelMode *>(*it); - for (k = 0; k < memos->memos.size(); ++k) + if (ci->GetParam(cm->Name, Param)) { - db << "MD MI " << memos->memos[k]->number << " " << memos->memos[k]->time << " " << memos->memos[k]->sender; - if (memos->memos[k]->HasFlag(MF_UNREAD)) - db << " UNREAD"; - if (memos->memos[k]->HasFlag(MF_RECEIPT)) - db << " RECEIPT"; - if (memos->memos[k]->HasFlag(MF_NOTIFYS)) - db << " NOTIFYS"; - db << " :" << memos->memos[k]->text << endl; + db << "MD MLP " << cm->NameAsString << " " << Param << endl; } } - if (ci->entry_message) - db << "MD ENTRYMSG :" << ci->entry_message << endl; - if (ci->bi) - db << "MD BI NAME " << ci->bi->nick << endl; - if (ci->botflags.FlagCount()) + } + if (!ci->memos.memos.empty()) + { + MemoInfo *memos = &ci->memos; + + for (unsigned k = 0; k < memos->memos.size(); ++k) { - db << "MD BI FLAGS"; - for (j = 0; BotFlags[j].Flag != -1; ++j) - if (ci->botflags.HasFlag(BotFlags[j].Flag)) - db << " " << BotFlags[j].Name; - db << endl; + db << "MD MI " << memos->memos[k]->number << " " << memos->memos[k]->time << " " << memos->memos[k]->sender; + if (memos->memos[k]->HasFlag(MF_UNREAD)) + db << " UNREAD"; + if (memos->memos[k]->HasFlag(MF_RECEIPT)) + db << " RECEIPT"; + if (memos->memos[k]->HasFlag(MF_NOTIFYS)) + db << " NOTIFYS"; + db << " :" << memos->memos[k]->text << endl; } - db << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << endl; - if (ci->capsmin) - db << "MD BI CAPSMIN " << ci->capsmin << endl; - if (ci->capspercent) - db << "MD BI CAPSPERCENT " << ci->capspercent << endl; - if (ci->floodlines) - db << "MD BI FLOODLINES " << ci->floodlines << endl; - if (ci->floodsecs) - db << "MD BI FLOODSECS " << ci->floodsecs << endl; - if (ci->repeattimes) - db << "MD BI REPEATTIMES " << ci->repeattimes << endl; - for (k = 0; k < ci->GetBadWordCount(); ++k) - db << "MD BI BADWORD " - << (ci->GetBadWord(k)->type == BW_ANY ? "ANY " : "") - << (ci->GetBadWord(k)->type == BW_SINGLE ? "SINGLE " : "") - << (ci->GetBadWord(k)->type == BW_START ? "START " : "") - << (ci->GetBadWord(k)->type == BW_END ? "END " : "") - << ":" << ci->GetBadWord(k)->word << endl; - - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, ci)); } + if (ci->entry_message) + db << "MD ENTRYMSG :" << ci->entry_message << endl; + if (ci->bi) + db << "MD BI NAME " << ci->bi->nick << endl; + if (ci->botflags.FlagCount()) + { + db << "MD BI FLAGS"; + for (int j = 0; BotFlags[j].Flag != -1; ++j) + if (ci->botflags.HasFlag(BotFlags[j].Flag)) + db << " " << BotFlags[j].Name; + db << endl; + } + db << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << endl; + if (ci->capsmin) + db << "MD BI CAPSMIN " << ci->capsmin << endl; + if (ci->capspercent) + db << "MD BI CAPSPERCENT " << ci->capspercent << endl; + if (ci->floodlines) + db << "MD BI FLOODLINES " << ci->floodlines << endl; + if (ci->floodsecs) + db << "MD BI FLOODSECS " << ci->floodsecs << endl; + if (ci->repeattimes) + db << "MD BI REPEATTIMES " << ci->repeattimes << endl; + for (unsigned k = 0; k < ci->GetBadWordCount(); ++k) + db << "MD BI BADWORD " + << (ci->GetBadWord(k)->type == BW_ANY ? "ANY " : "") + << (ci->GetBadWord(k)->type == BW_SINGLE ? "SINGLE " : "") + << (ci->GetBadWord(k)->type == BW_START ? "START " : "") + << (ci->GetBadWord(k)->type == BW_END ? "END " : "") + << ":" << ci->GetBadWord(k)->word << endl; + + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, ci)); } - for (i = 0; i < akills.count; ++i) + db << "OS STATS " << maxusercnt << " " << maxusertime << endl; + + if (SGLine) { - Akill *ak = static_cast<Akill *>(akills.list[i]); - db << "OS AKILL " << ak->user << " " << ak->host << " " << ak->by << " " << ak->seton << " " << ak->expires << " :" << ak->reason << endl; + for (unsigned i = 0; i < SGLine->GetCount(); ++i) + { + XLine *x = SGLine->GetEntry(i); + db << "OS AKILL " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl; + } } - db << "OS STATS " << maxusercnt << " " << maxusertime << endl; - SXLine *sx; - for (i = 0; i < sglines.count; ++i) + if (SNLine) { - sx = static_cast<SXLine *>(sglines.list[i]); - db << "OS SGLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl; + for (unsigned i = 0; i < SNLine->GetCount(); ++i) + { + XLine *x = SNLine->GetEntry(i); + db << "OS SNLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl; + } } - for (i = 0; i < sqlines.count; ++i) + + if (SQLine) { - sx = static_cast<SXLine *>(sqlines.list[i]); - db << "OS SQLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl; + for (unsigned i = 0; i < SQLine->GetCount(); ++i) + { + XLine *x = SQLine->GetEntry(i); + db << "OS SQLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl; + } } - for (i = 0; i < szlines.count; ++i) + + if (SZLine) { - sx = static_cast<SXLine *>(szlines.list[i]); - db << "OS SZLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl; + for (unsigned i = 0; i < SZLine->GetCount(); ++i) + { + XLine *x = SZLine->GetEntry(i); + db << "OS SZLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl; + } } - for (i = 0; i < nexceptions; i++) + for (int i = 0; i < nexceptions; i++) { db << "OS EXCEPTION " << exceptions[i].mask << " " << exceptions[i].limit << " " << exceptions[i].who << " " << exceptions[i].time << " " << exceptions[i].expires << " " << exceptions[i].reason << endl; } diff --git a/src/core/enc_md5.c b/src/core/enc_md5.cpp index 1c46ca72b..1c46ca72b 100644 --- a/src/core/enc_md5.c +++ b/src/core/enc_md5.cpp diff --git a/src/core/enc_none.c b/src/core/enc_none.cpp index 280c86bd2..280c86bd2 100644 --- a/src/core/enc_none.c +++ b/src/core/enc_none.cpp diff --git a/src/core/enc_old.c b/src/core/enc_old.cpp index 68eece13c..68eece13c 100644 --- a/src/core/enc_old.c +++ b/src/core/enc_old.cpp diff --git a/src/core/enc_sha1.c b/src/core/enc_sha1.cpp index b4ac2a4e2..b4ac2a4e2 100644 --- a/src/core/enc_sha1.c +++ b/src/core/enc_sha1.cpp diff --git a/src/core/enc_sha256.c b/src/core/enc_sha256.cpp index ef1ed7a00..ef1ed7a00 100644 --- a/src/core/enc_sha256.c +++ b/src/core/enc_sha256.cpp diff --git a/src/core/hs_del.c b/src/core/hs_del.cpp index 286366735..e86db7e81 100644 --- a/src/core/hs_del.c +++ b/src/core/hs_del.cpp @@ -52,6 +52,11 @@ class CommandHSDel : public Command { syntax_error(Config.s_HostServ, u, "DEL", HOST_DEL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DEL); + } }; class HSDel : public Module @@ -63,13 +68,7 @@ class HSDel : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSDel()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DEL); + this->AddCommand(HostServ, new CommandHSDel()); } }; diff --git a/src/core/hs_delall.c b/src/core/hs_delall.cpp index b40565e3d..97a09a073 100644 --- a/src/core/hs_delall.c +++ b/src/core/hs_delall.cpp @@ -23,10 +23,8 @@ class CommandHSDelAll : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - int i; const char *nick = params[0].c_str(); NickAlias *na; - NickCore *nc; if ((na = findnick(nick))) { if (na->HasFlag(NS_FORBIDDEN)) @@ -35,10 +33,10 @@ class CommandHSDelAll : public Command return MOD_CONT; } FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na)); - nc = na->nc; - for (i = 0; i < nc->aliases.count; ++i) + NickCore *nc = na->nc; + for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it) { - na = static_cast<NickAlias *>(nc->aliases.list[i]); + na = *it; na->hostinfo.RemoveVhost(); } Alog() << "vHosts for all nicks in group \002" << nc->display << "\002 deleted by oper \002" << u->nick << "\002"; @@ -59,6 +57,11 @@ class CommandHSDelAll : public Command { syntax_error(Config.s_HostServ, u, "DELALL", HOST_DELALL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DELALL); + } }; class HSDelAll : public Module @@ -70,13 +73,7 @@ class HSDelAll : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSDelAll()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DELALL); + this->AddCommand(HostServ, new CommandHSDelAll()); } }; diff --git a/src/core/hs_group.c b/src/core/hs_group.cpp index e4117ba9c..d71c4088d 100644 --- a/src/core/hs_group.c +++ b/src/core/hs_group.cpp @@ -45,6 +45,11 @@ class CommandHSGroup : public Command notice_help(Config.s_HostServ, u, HOST_HELP_GROUP); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_GROUP); + } }; class HSGroup : public Module @@ -56,13 +61,7 @@ class HSGroup : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSGroup()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_GROUP); + this->AddCommand(HostServ, new CommandHSGroup()); } }; diff --git a/src/core/hs_help.c b/src/core/hs_help.cpp index 0522c09d4..5cc7e5129 100644 --- a/src/core/hs_help.c +++ b/src/core/hs_help.cpp @@ -24,14 +24,15 @@ class CommandHSHelp : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - mod_help_cmd(Config.s_HostServ, u, HOSTSERV, params[0].c_str()); + mod_help_cmd(HostServ, u, params[0].c_str()); return MOD_CONT; } void OnSyntaxError(User *u, const ci::string &subcommand) { notice_help(Config.s_HostServ, u, HOST_HELP, Config.s_HostServ); - FOREACH_MOD(I_OnHostServHelp, OnHostServHelp(u)); + for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it) + it->second->OnServHelp(u); } }; @@ -44,7 +45,7 @@ class HSHelp : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSHelp()); + this->AddCommand(HostServ, new CommandHSHelp()); } }; diff --git a/src/core/hs_list.c b/src/core/hs_list.cpp index e86f2d0dc..d92822b63 100644 --- a/src/core/hs_list.c +++ b/src/core/hs_list.cpp @@ -53,47 +53,46 @@ class CommandHSList : public Command } } - for (int j = 0; j < 1024; ++j) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (NickAlias *na = nalists[j]; na; na = na->next) - { - if (!na->hostinfo.HasVhost()) - continue; + NickAlias *na = it->second; + + if (!na->hostinfo.HasVhost()) + continue; - if (!key.empty() && key[0] != '#') + if (!key.empty() && key[0] != '#') + { + if ((Anope::Match(na->nick, key) || Anope::Match(na->hostinfo.GetHost(), key.c_str())) && display_counter < Config.NSListMax) { - if ((Anope::Match(na->nick, key) || Anope::Match(na->hostinfo.GetHost(), key.c_str())) && display_counter < Config.NSListMax) - { - ++display_counter; - time_t time = na->hostinfo.GetTime(); - tm = localtime(&time); - strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); - if (!na->hostinfo.GetIdent().empty()) - notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); - else - notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); - } + ++display_counter; + time_t time = na->hostinfo.GetTime(); + tm = localtime(&time); + strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); + if (!na->hostinfo.GetIdent().empty()) + notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); + else + notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); } - else + } + else + { + /** + * List the host if its in the display range, and not more + * than NSListMax records have been displayed... + **/ + if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config.NSListMax) { - /** - * List the host if its in the display range, and not more - * than NSListMax records have been displayed... - **/ - if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config.NSListMax) - { - ++display_counter; - time_t time = na->hostinfo.GetTime(); - tm = localtime(&time); - strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); - if (!na->hostinfo.GetIdent().empty()) - notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); - else - notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); - } + ++display_counter; + time_t time = na->hostinfo.GetTime(); + tm = localtime(&time); + strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); + if (!na->hostinfo.GetIdent().empty()) + notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); + else + notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf); } - ++counter; } + ++counter; } if (!key.empty()) notice_lang(Config.s_HostServ, u, HOST_LIST_KEY_FOOTER, key.c_str(), display_counter); @@ -112,6 +111,11 @@ class CommandHSList : public Command notice_help(Config.s_HostServ, u, HOST_HELP_LIST); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_LIST); + } }; class HSList : public Module @@ -123,13 +127,7 @@ class HSList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSList()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_LIST); + this->AddCommand(HostServ, new CommandHSList()); } }; diff --git a/src/core/hs_off.c b/src/core/hs_off.cpp index 5943e8850..0a483e2a4 100644 --- a/src/core/hs_off.c +++ b/src/core/hs_off.cpp @@ -41,6 +41,11 @@ class CommandHSOff : public Command notice_help(Config.s_HostServ, u, HOST_HELP_OFF); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_OFF); + } }; class HSOff : public Module @@ -52,13 +57,7 @@ class HSOff : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSOff()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_OFF); + this->AddCommand(HostServ, new CommandHSOff()); } }; diff --git a/src/core/hs_on.c b/src/core/hs_on.cpp index 2194e2d2b..4fd415ead 100644 --- a/src/core/hs_on.c +++ b/src/core/hs_on.cpp @@ -55,6 +55,11 @@ class CommandHSOn : public Command notice_help(Config.s_HostServ, u, HOST_HELP_ON); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_ON); + } }; class HSOn : public Module @@ -66,13 +71,7 @@ class HSOn : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSOn()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_ON); + this->AddCommand(HostServ, new CommandHSOn()); } }; diff --git a/src/core/hs_set.c b/src/core/hs_set.cpp index b382cb0ea..3aeb5c6be 100644 --- a/src/core/hs_set.c +++ b/src/core/hs_set.cpp @@ -149,6 +149,11 @@ class CommandHSSet : public Command { syntax_error(Config.s_HostServ, u, "SET", HOST_SET_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SET); + } }; class HSSet : public Module @@ -160,13 +165,7 @@ class HSSet : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSSet()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SET); + this->AddCommand(HostServ, new CommandHSSet()); } }; diff --git a/src/core/hs_setall.c b/src/core/hs_setall.cpp index 9afb26206..88a47dc9a 100644 --- a/src/core/hs_setall.c +++ b/src/core/hs_setall.cpp @@ -147,6 +147,11 @@ class CommandHSSetAll : public Command { syntax_error(Config.s_HostServ, u, "SETALL", HOST_SETALL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SETALL); + } }; class HSSetAll : public Module @@ -158,13 +163,7 @@ class HSSetAll : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(HOSTSERV, new CommandHSSetAll()); - - ModuleManager::Attach(I_OnHostServHelp, this); - } - void OnHostServHelp(User *u) - { - notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SETALL); + this->AddCommand(HostServ, new CommandHSSetAll()); } }; diff --git a/src/core/ms_cancel.c b/src/core/ms_cancel.cpp index c2eeee4c5..4528134fa 100644 --- a/src/core/ms_cancel.c +++ b/src/core/ms_cancel.cpp @@ -69,6 +69,11 @@ class CommandMSCancel : public Command { syntax_error(Config.s_MemoServ, u, "CANCEL", MEMO_CANCEL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CANCEL); + } }; class MSCancel : public Module @@ -79,13 +84,7 @@ class MSCancel : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSCancel()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CANCEL); + this->AddCommand(MemoServ, new CommandMSCancel()); } }; diff --git a/src/core/ms_check.c b/src/core/ms_check.cpp index 47270a4ab..87d4a4417 100644 --- a/src/core/ms_check.c +++ b/src/core/ms_check.cpp @@ -85,6 +85,11 @@ class CommandMSCheck : public Command { syntax_error(Config.s_MemoServ, u, "CHECK", MEMO_CHECK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CHECK); + } }; class MSCheck : public Module @@ -95,13 +100,7 @@ class MSCheck : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSCheck()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CHECK); + this->AddCommand(MemoServ, new CommandMSCheck()); } }; diff --git a/src/core/ms_del.c b/src/core/ms_del.cpp index f5c27cc4e..e10b7f3fb 100644 --- a/src/core/ms_del.c +++ b/src/core/ms_del.cpp @@ -14,7 +14,33 @@ #include "module.h" -int del_memo_callback(User *u, int num, va_list args); +class MemoDelCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + MemoInfo *mi; + public: + MemoDelCallback(User *_u, ChannelInfo *_ci, MemoInfo *_mi, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), mi(_mi) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > mi->memos.size()) + return; + + if (ci) + { + FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, Number - 1)); + } + else + { + FOREACH_MOD(I_OnMemoDel, OnMemoDel(u->Account(), mi, Number - 1)); + } + + delmemo(mi, Number - 1); + } +}; class CommandMSDel : public Command { @@ -28,17 +54,15 @@ class CommandMSDel : public Command MemoInfo *mi; ChannelInfo *ci = NULL; ci::string numstr = params.size() ? params[0] : "", chan; - int last, last0; unsigned i; - char buf[BUFSIZE], *end; - int delcount, count, left; + int last; if (!numstr.empty() && numstr[0] == '#') { chan = numstr; numstr = params.size() > 1 ? params[1] : ""; - if (!(ci = cs_findchan(chan.c_str()))) + if (!(ci = cs_findchan(chan))) { notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str()); return MOD_CONT; @@ -71,37 +95,7 @@ class CommandMSDel : public Command else { if (isdigit(numstr[0])) - { - /* Delete a specific memo or memos. */ - last = -1; /* Last memo deleted */ - last0 = -1; /* Beginning of range of last memos deleted */ - end = buf; - left = sizeof(buf); - delcount = process_numlist(numstr.c_str(), &count, del_memo_callback, u, mi, &last, &last0, &end, &left, ci); - if (last != -1) - { - /* Some memos got deleted; tell them which ones. */ - if (delcount > 1) - { - if (last0 != last) - end += snprintf(end, sizeof(buf) - (end - buf), ",%d-%d", last0, last); - else - end += snprintf(end, sizeof(buf) - (end - buf), ",%d", last); - /* "buf+1" here because *buf == ',' */ - notice_lang(Config.s_MemoServ, u, MEMO_DELETED_SEVERAL, buf + 1); - } - else - notice_lang(Config.s_MemoServ, u, MEMO_DELETED_ONE, last); - } - else - { - /* No memos were deleted. Tell them so. */ - if (count == 1) - notice_lang(Config.s_MemoServ, u, MEMO_DOES_NOT_EXIST, atoi(numstr.c_str())); - else - notice_lang(Config.s_MemoServ, u, MEMO_DELETED_NONE); - } - } + (new MemoDelCallback(u, ci, mi, numstr.c_str()))->Process(); else if (numstr == "LAST") { /* Delete last memo. */ @@ -158,6 +152,11 @@ class CommandMSDel : public Command { syntax_error(Config.s_MemoServ, u, "DEL", MEMO_DEL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_DEL); + } }; class MSDel : public Module @@ -168,61 +167,7 @@ class MSDel : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSDel()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_DEL); } }; -/** - * Delete a single memo from a MemoInfo. callback function - * @param u User Struct - * @param int Number - * @param va_list Variable Arguemtns - * @return 1 if successful, 0 if it fails - */ -int del_memo_callback(User *u, int num, va_list args) -{ - MemoInfo *mi = va_arg(args, MemoInfo *); - int *last = va_arg(args, int *); - int *last0 = va_arg(args, int *); - char **end = va_arg(args, char **); - int *left = va_arg(args, int *); - ChannelInfo *ci = va_arg(args, ChannelInfo *); - - if (ci) - { - FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, num)); - } - else - { - FOREACH_MOD(I_OnMemoDel, OnMemoDel(u->Account(), mi, num)); - } - if (delmemo(mi, num)) - { - if (num != (*last) + 1) - { - if (*last != -1) - { - int len; - if (*last0 != *last) - len = snprintf(*end, *left, ",%d-%d", *last0, *last); - else - len = snprintf(*end, *left, ",%d", *last); - *end += len; - *left -= len; - } - *last0 = num; - } - *last = num; - return 1; - } - else - return 0; -} - MODULE_INIT(MSDel) diff --git a/src/core/ms_help.c b/src/core/ms_help.cpp index baa74aa93..2aa837d64 100644 --- a/src/core/ms_help.c +++ b/src/core/ms_help.cpp @@ -24,14 +24,15 @@ class CommandMSHelp : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - mod_help_cmd(Config.s_MemoServ, u, MEMOSERV, params[0].c_str()); + mod_help_cmd(MemoServ, u, params[0].c_str()); return MOD_CONT; } void OnSyntaxError(User *u, const ci::string &subcommand) { notice_help(Config.s_MemoServ, u, MEMO_HELP_HEADER); - FOREACH_MOD(I_OnMemoServHelp, OnMemoServHelp(u)); + for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it) + it->second->OnServHelp(u); notice_help(Config.s_MemoServ, u, MEMO_HELP_FOOTER, Config.s_ChanServ); } }; @@ -44,7 +45,7 @@ class MSHelp : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSHelp()); + this->AddCommand(MemoServ, new CommandMSHelp()); } }; diff --git a/src/core/ms_info.c b/src/core/ms_info.cpp index a1066f466..81650d584 100644 --- a/src/core/ms_info.c +++ b/src/core/ms_info.cpp @@ -198,6 +198,11 @@ class CommandMSInfo : public Command return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_INFO); + } }; class MSInfo : public Module @@ -208,13 +213,7 @@ class MSInfo : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSInfo()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_INFO); + this->AddCommand(MemoServ, new CommandMSInfo()); } }; diff --git a/src/core/ms_list.c b/src/core/ms_list.cpp index 5e97615ab..088fcdb12 100644 --- a/src/core/ms_list.c +++ b/src/core/ms_list.cpp @@ -14,8 +14,46 @@ #include "module.h" -int list_memo_callback(User *u, int num, va_list args); -int list_memo(User *u, int index, MemoInfo *mi, int *sent_header, int newi, const char *chan); +class MemoListCallback : public NumberList +{ + User *u; + ChannelInfo *ci; + MemoInfo *mi; + bool SentHeader; + public: + MemoListCallback(User *_u, ChannelInfo *_ci, MemoInfo *_mi, const std::string &list) : NumberList(list, false), u(_u), ci(_ci), mi(_mi), SentHeader(false) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > mi->memos.size()) + return; + + if (!SentHeader) + { + SentHeader = true; + if (ci) + notice_lang(Config.s_MemoServ, u, MEMO_LIST_CHAN_MEMOS, ci->name.c_str(), Config.s_MemoServ, ci->name.c_str()); + else + notice_lang(Config.s_MemoServ, u, MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ); + + notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER); + } + + DoList(u, ci, mi, Number - 1); + } + + static void DoList(User *u, ChannelInfo *ci, MemoInfo *mi, unsigned index) + { + Memo *m = mi->memos[index]; + struct tm tm = *localtime(&m->time); + char timebuf[64]; + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); + timebuf[sizeof(timebuf) - 1] = 0; /* just in case */ + notice_lang(Config.s_MemoServ, u, MEMO_LIST_FORMAT, (m->HasFlag(MF_UNREAD)) ? '*' : ' ', m->number, m->sender.c_str(), timebuf); + } +}; class CommandMSList : public Command { @@ -36,7 +74,7 @@ class CommandMSList : public Command chan = param; param = params.size() > 1 ? params[1] : ""; - if (!(ci = cs_findchan(chan.c_str()))) + if (!(ci = cs_findchan(chan))) { notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str()); return MOD_CONT; @@ -63,9 +101,8 @@ class CommandMSList : public Command } else { - int sent_header = 0; if (!param.empty() && isdigit(param[0])) - process_numlist(param.c_str(), NULL, list_memo_callback, u, mi, &sent_header, chan.empty() ? NULL : chan.c_str()); + (new MemoListCallback(u, ci, mi, param.c_str()))->Process(); else { if (!param.empty()) @@ -84,11 +121,25 @@ class CommandMSList : public Command return MOD_CONT; } } + + bool SentHeader = false; + for (i = 0; i < mi->memos.size(); ++i) { if (!param.empty() && !(mi->memos[i]->HasFlag(MF_UNREAD))) continue; - list_memo(u, i, mi, &sent_header, !param.empty(), chan.empty() ? NULL : chan.c_str()); + + if (!SentHeader) + { + SentHeader = true; + if (ci) + notice_lang(Config.s_MemoServ, u, !param.empty() ? MEMO_LIST_CHAN_NEW_MEMOS : MEMO_LIST_CHAN_MEMOS, ci->name.c_str(), Config.s_MemoServ, ci->name.c_str()); + else + notice_lang(Config.s_MemoServ, u, !param.empty() ? MEMO_LIST_NEW_MEMOS : MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ); + notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER); + } + + MemoListCallback::DoList(u, ci, mi, i); } } } @@ -105,6 +156,11 @@ class CommandMSList : public Command { syntax_error(Config.s_MemoServ, u, "LIST", MEMO_LIST_SYNTAX); } + + void OnServCommand(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_LIST); + } }; class MSList : public Module @@ -115,72 +171,8 @@ class MSList : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSList()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_LIST); + this->AddCommand(MemoServ, new CommandMSList()); } }; -/** - * list memno callback function - * @param u User Struct - * @param int Memo number - * @param va_list List of arguements - * @return result form list_memo() - */ -int list_memo_callback(User *u, int num, va_list args) -{ - MemoInfo *mi = va_arg(args, MemoInfo *); - int *sent_header = va_arg(args, int *); - const char *chan = va_arg(args, const char *); - int i; - - for (i = 0; i < mi->memos.size(); ++i) - { - if (mi->memos[i]->number == num) - break; - } - /* Range checking done by list_memo() */ - return list_memo(u, i, mi, sent_header, 0, chan); -} - -/** - * Display a single memo entry, possibly printing the header first. - * @param u User Struct - * @param int Memo index - * @param mi MemoInfo Struct - * @param send_header If we are to send the headers - * @param newi If we are listing new memos - * @param chan Channel name - * @return MOD_CONT - */ -int list_memo(User *u, int index, MemoInfo *mi, int *sent_header, int newi, const char *chan) -{ - Memo *m; - char timebuf[64]; - struct tm tm; - - if (index < 0 || index >= mi->memos.size()) - return 0; - if (!*sent_header) - { - if (chan) - notice_lang(Config.s_MemoServ, u, newi ? MEMO_LIST_CHAN_NEW_MEMOS : MEMO_LIST_CHAN_MEMOS, chan, Config.s_MemoServ, chan); - else - notice_lang(Config.s_MemoServ, u, newi ? MEMO_LIST_NEW_MEMOS : MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ); - notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER); - *sent_header = 1; - } - m = mi->memos[index]; - tm = *localtime(&m->time); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); - timebuf[sizeof(timebuf) - 1] = 0; /* just in case */ - notice_lang(Config.s_MemoServ, u, MEMO_LIST_FORMAT, (m->HasFlag(MF_UNREAD)) ? '*' : ' ', m->number, m->sender.c_str(), timebuf); - return 1; -} - MODULE_INIT(MSList) diff --git a/src/core/ms_read.c b/src/core/ms_read.cpp index d5e10b213..9553127af 100644 --- a/src/core/ms_read.c +++ b/src/core/ms_read.cpp @@ -14,9 +14,42 @@ #include "module.h" -int read_memo_callback(User *u, int num, va_list args); -int read_memo(User *u, int index, MemoInfo *mi, const char *chan); -extern void rsend_notify(User *u, Memo *m, const char *chan); +class MemoListCallback : public NumberList +{ + User *u; + MemoInfo *mi; + public: + MemoListCallback(User *_u, MemoInfo *_mi, const std::string &numlist) : NumberList(numlist, false), u(_u), mi(_mi) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > mi->memos.size()) + return; + + MemoListCallback::DoRead(u, mi, NULL, Number - 1); + } + + static void DoRead(User *u, MemoInfo *mi, ChannelInfo *ci, unsigned index) + { + Memo *m = mi->memos[index]; + struct tm tm = *localtime(&m->time); + char timebuf[64]; + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); + timebuf[sizeof(timebuf) - 1] = 0; + if (ci) + notice_lang(Config.s_MemoServ, u, MEMO_CHAN_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, ci->name.c_str(), m->number); + else + notice_lang(Config.s_MemoServ, u, MEMO_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, m->number); + notice_lang(Config.s_MemoServ, u, MEMO_TEXT, m->text); + m->UnsetFlag(MF_UNREAD); + + /* Check if a receipt notification was requested */ + if (m->HasFlag(MF_RECEIPT)) + rsend_notify(u, m, ci ? ci->name.c_str() : NULL); + } +}; class CommandMSRead : public Command { @@ -28,16 +61,16 @@ class CommandMSRead : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { MemoInfo *mi; - ChannelInfo *ci; + ChannelInfo *ci = NULL; ci::string numstr = params.size() ? params[0] : "", chan; - int num, count; + int num; if (!numstr.empty() && numstr[0] == '#') { chan = numstr; numstr = params.size() > 1 ? params[1] : ""; - if (!(ci = cs_findchan(chan.c_str()))) + if (!(ci = cs_findchan(chan))) { notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str()); return MOD_CONT; @@ -73,7 +106,7 @@ class CommandMSRead : public Command { if (mi->memos[i]->HasFlag(MF_UNREAD)) { - read_memo(u, i, mi, !chan.empty() ? chan.c_str() : NULL); + MemoListCallback::DoRead(u, mi, ci, i); ++readcount; } } @@ -88,17 +121,11 @@ class CommandMSRead : public Command else if (numstr == "LAST") { for (i = 0; i < mi->memos.size() - 1; ++i); - read_memo(u, i, mi, !chan.empty() ? chan.c_str() : NULL); + MemoListCallback::DoRead(u, mi, ci, i); } else /* number[s] */ { - if (!process_numlist(numstr.c_str(), &count, read_memo_callback, u, mi, !chan.empty() ? chan.c_str() : NULL)) - { - if (count == 1) - notice_lang(Config.s_MemoServ, u, MEMO_DOES_NOT_EXIST, num); - else - notice_lang(Config.s_MemoServ, u, MEMO_LIST_NOT_FOUND, numstr.c_str()); - } + (new MemoListCallback(u, mi, numstr.c_str()))->Process(); } } return MOD_CONT; @@ -114,6 +141,11 @@ class CommandMSRead : public Command { syntax_error(Config.s_MemoServ, u, "READ", MEMO_READ_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_READ); + } }; class MSRead : public Module @@ -124,70 +156,8 @@ class MSRead : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSRead()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_READ); + this->AddCommand(MemoServ, new CommandMSRead()); } }; -/** - * Read a memo callback function - * @param u User Struct - * @param int Index number - * @param va_list variable arguements - * @return result of read_memo() - */ -int read_memo_callback(User *u, int num, va_list args) -{ - MemoInfo *mi = va_arg(args, MemoInfo *); - const char *chan = va_arg(args, const char *); - int i; - - for (i = 0; i < mi->memos.size(); ++i) - { - if (mi->memos[i]->number == num) - break; - } - /* Range check done in read_memo */ - return read_memo(u, i, mi, chan); -} - -/** - * Read a memo - * @param u User Struct - * @param int Index number - * @param mi MemoInfo struct - * @param chan Channel Name - * @return 1 on success, 0 if failed - */ -int read_memo(User *u, int index, MemoInfo *mi, const char *chan) -{ - Memo *m; - char timebuf[64]; - struct tm tm; - - if (index < 0 || index >= mi->memos.size()) - return 0; - m = mi->memos[index]; - tm = *localtime(&m->time); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); - timebuf[sizeof(timebuf) - 1] = 0; - if (chan) - notice_lang(Config.s_MemoServ, u, MEMO_CHAN_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, chan, m->number); - else - notice_lang(Config.s_MemoServ, u, MEMO_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, m->number); - notice_lang(Config.s_MemoServ, u, MEMO_TEXT, m->text); - m->UnsetFlag(MF_UNREAD); - - /* Check if a receipt notification was requested */ - if (m->HasFlag(MF_RECEIPT)) - rsend_notify(u, m, chan); - - return 1; -} - MODULE_INIT(MSRead) diff --git a/src/core/ms_rsend.c b/src/core/ms_rsend.cpp index d8ebc1245..5ad43ac49 100644 --- a/src/core/ms_rsend.c +++ b/src/core/ms_rsend.cpp @@ -69,6 +69,11 @@ class CommandMSRSend : public Command { syntax_error(Config.s_MemoServ, u, "RSEND", MEMO_RSEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_RSEND); + } }; class MSRSend : public Module @@ -79,16 +84,10 @@ class MSRSend : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSRSend()); + this->AddCommand(MemoServ, new CommandMSRSend()); if (!Config.MSMemoReceipt) throw ModuleException("Don't like memo reciepts, or something."); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_RSEND); } }; diff --git a/src/core/ms_send.c b/src/core/ms_send.cpp index 12123fda8..71479924c 100644 --- a/src/core/ms_send.c +++ b/src/core/ms_send.cpp @@ -40,6 +40,11 @@ class CommandMSSend : public Command { syntax_error(Config.s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SEND); + } }; class MSSend : public Module @@ -50,13 +55,7 @@ class MSSend : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSSend()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SEND); + this->AddCommand(MemoServ, new CommandMSSend()); } }; diff --git a/src/core/ms_sendall.c b/src/core/ms_sendall.cpp index 4a09457e2..9150152df 100644 --- a/src/core/ms_sendall.c +++ b/src/core/ms_sendall.cpp @@ -23,8 +23,7 @@ class CommandMSSendAll : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - int i, z = 1; - NickCore *nc; + int z = 1; const char *text = params[0].c_str(); if (readonly) @@ -33,14 +32,15 @@ class CommandMSSendAll : public Command return MOD_CONT; } - for (i = 0; i < 1024; ++i) + NickAlias *na = findnick(u->nick); + + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (nc = nclists[i]; nc; nc = nc->next) - { - if (stricmp(u->nick.c_str(), nc->display)) - memo_send(u, nc->display, text, z); - } /* /nc */ - } /* /i */ + NickCore *nc = it->second; + + if ((na && na->nc == nc) || stricmp(u->nick.c_str(), nc->display)) + memo_send(u, nc->display, text, z); + } notice_lang(Config.s_MemoServ, u, MEMO_MASS_SENT); return MOD_CONT; @@ -56,6 +56,11 @@ class CommandMSSendAll : public Command { syntax_error(Config.s_MemoServ, u, "SENDALL", MEMO_SEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SENDALL); + } }; class MSSendAll : public Module @@ -66,13 +71,7 @@ class MSSendAll : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSSendAll()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SENDALL); + this->AddCommand(MemoServ, new CommandMSSendAll()); } }; diff --git a/src/core/ms_set.c b/src/core/ms_set.cpp index 150224f1e..d915d7856 100644 --- a/src/core/ms_set.c +++ b/src/core/ms_set.cpp @@ -83,7 +83,7 @@ class CommandMSSet : public Command p1 = p2; p2 = p3; p3 = params.size() > 4 ? params[4] : ""; - if (!(ci = cs_findchan(chan.c_str()))) + if (!(ci = cs_findchan(chan))) { notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str()); return MOD_CONT; @@ -100,7 +100,7 @@ class CommandMSSet : public Command if (!p2.empty() && p2 != "HARD" && chan.empty()) { NickAlias *na; - if (!(na = findnick(p1.c_str()))) + if (!(na = findnick(p1))) { notice_lang(Config.s_MemoServ, u, NICK_X_NOT_REGISTERED, p1.c_str()); return MOD_CONT; @@ -251,6 +251,11 @@ class CommandMSSet : public Command { syntax_error(Config.s_MemoServ, u, "SET", MEMO_SET_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SET); + } }; class MSSet : public Module @@ -262,13 +267,7 @@ class MSSet : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSSet()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SET); + this->AddCommand(MemoServ, new CommandMSSet()); } }; diff --git a/src/core/ms_staff.c b/src/core/ms_staff.cpp index 939322269..3d2877e44 100644 --- a/src/core/ms_staff.c +++ b/src/core/ms_staff.cpp @@ -23,8 +23,7 @@ class CommandMSStaff : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - NickCore *nc; - int i, z = 0; + int z = 0; const char *text = params[0].c_str(); if (readonly) @@ -33,14 +32,14 @@ class CommandMSStaff : public Command return MOD_CONT; } - for (i = 0; i < 1024; ++i) + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (nc = nclists[i]; nc; nc = nc->next) - { - if (nc->IsServicesOper()) - memo_send(u, nc->display, text, z); - } + NickCore *nc = it->second; + + if (nc->IsServicesOper()) + memo_send(u, nc->display, text, z); } + return MOD_CONT; } @@ -54,6 +53,11 @@ class CommandMSStaff : public Command { syntax_error(Config.s_MemoServ, u, "STAFF", MEMO_STAFF_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_STAFF); + } }; class MSStaff : public Module @@ -64,13 +68,7 @@ class MSStaff : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(MEMOSERV, new CommandMSStaff()); - - ModuleManager::Attach(I_OnMemoServHelp, this); - } - void OnMemoServHelp(User *u) - { - notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_STAFF); + this->AddCommand(MemoServ, new CommandMSStaff()); } }; diff --git a/src/core/ns_access.c b/src/core/ns_access.cpp index bebf1491f..c578e6095 100644 --- a/src/core/ns_access.c +++ b/src/core/ns_access.cpp @@ -124,7 +124,7 @@ class CommandNSAccess : public Command const char *mask = params.size() > 1 ? params[1].c_str() : NULL; NickAlias *na; - if (cmd == "LIST" && u->Account()->IsServicesOper() && mask && (na = findnick(params[1].c_str()))) + if (cmd == "LIST" && u->Account()->IsServicesOper() && mask && (na = findnick(params[1]))) return this->DoServAdminList(u, params, na->nc); if (mask && !strchr(mask, '@')) @@ -160,6 +160,11 @@ class CommandNSAccess : public Command { syntax_error(Config.s_NickServ, u, "ACCESS", NICK_ACCESS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ACCESS); + } }; class NSAccess : public Module @@ -171,13 +176,7 @@ class NSAccess : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSAccess()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ACCESS); + this->AddCommand(NickServ, new CommandNSAccess()); } }; diff --git a/src/core/ns_alist.c b/src/core/ns_alist.cpp index 57b09ab10..a904fe9b0 100644 --- a/src/core/ns_alist.c +++ b/src/core/ns_alist.cpp @@ -88,37 +88,35 @@ class CommandNSAList : public Command notice_lang(Config.s_NickServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1); else { - int i, level; + int level; int chan_count = 0; int match_count = 0; - ChannelInfo *ci; notice_lang(Config.s_NickServ, u, is_servadmin ? NICK_ALIST_HEADER_X : NICK_ALIST_HEADER, na->nick); - for (i = 0; i < 256; ++i) + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) { - for (ci = chanlists[i]; ci; ci = ci->next) + ChannelInfo *ci = it->second; + + if ((level = get_access_level(ci, na))) { - if ((level = get_access_level(ci, na))) - { - ++chan_count; + ++chan_count; - if (min_level > level) - continue; + if (min_level > level) + continue; - ++match_count; + ++match_count; - if ((ci->HasFlag(CI_XOP)) || level == ACCESS_FOUNDER) - { - const char *xop; + if ((ci->HasFlag(CI_XOP)) || level == ACCESS_FOUNDER) + { + const char *xop; - xop = get_xop_level(level); + xop = get_xop_level(level); - notice_lang(Config.s_NickServ, u, NICK_ALIST_XOP_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), xop, ci->desc ? ci->desc : ""); - } - else - notice_lang(Config.s_NickServ, u, NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), level, ci->desc ? ci->desc : ""); + notice_lang(Config.s_NickServ, u, NICK_ALIST_XOP_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), xop, ci->desc ? ci->desc : ""); } + else + notice_lang(Config.s_NickServ, u, NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), level, ci->desc ? ci->desc : ""); } } @@ -136,6 +134,11 @@ class CommandNSAList : public Command return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ALIST); + } }; class NSAList : public Module @@ -147,13 +150,7 @@ class NSAList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSAList()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ALIST); + this->AddCommand(NickServ, new CommandNSAList()); } }; diff --git a/src/core/ns_drop.c b/src/core/ns_drop.cpp index ce87626c1..7383706d9 100644 --- a/src/core/ns_drop.c +++ b/src/core/ns_drop.cpp @@ -42,7 +42,7 @@ class CommandNSDrop : public Command if ((nr = findrequestnick(nick)) && u->Account()->IsServicesOper()) { if (Config.WallDrop) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick); Alog() << Config.s_NickServ << ": " << u->GetMask() << " dropped nickname " << nr->nick << " (e-mail: " << nr->email << ")"; delete nr; notice_lang(Config.s_NickServ, u, NICK_X_DROPPED, nick); @@ -69,7 +69,10 @@ class CommandNSDrop : public Command notice_lang(Config.s_NickServ, u, READ_ONLY_MODE); if (ircd->sqline && (na->HasFlag(NS_FORBIDDEN))) - ircdproto->SendSQLineDel(na->nick); + { + XLine x(na->nick); + ircdproto->SendSQLineDel(&x); + } Alog() << Config.s_NickServ << ": " << u->GetMask() << " dropped nickname " << na->nick << " (group " << na->nc->display << ") (e-mail: " << (na->nc->email ? na->nc->email : "none") << ")"; delete na; @@ -79,7 +82,7 @@ class CommandNSDrop : public Command if (!is_mine) { if (Config.WallDrop) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick); notice_lang(Config.s_NickServ, u, NICK_X_DROPPED, nick); } else @@ -104,6 +107,11 @@ class CommandNSDrop : public Command return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_DROP); + } }; class NSDrop : public Module @@ -115,13 +123,7 @@ class NSDrop : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSDrop()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_DROP); + this->AddCommand(NickServ, new CommandNSDrop()); } }; diff --git a/src/core/ns_forbid.c b/src/core/ns_forbid.cpp index 14101a335..61a28e552 100644 --- a/src/core/ns_forbid.c +++ b/src/core/ns_forbid.cpp @@ -69,10 +69,13 @@ class CommandNSForbid : public Command if (ircd->sqline) - ircdproto->SendSQLine(na->nick, reason ? reason : "Forbidden"); + { + XLine x(na->nick, reason ? reason : "Forbidden"); + ircdproto->SendSQLine(&x); + } if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used FORBID on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used FORBID on \2%s\2", u->nick.c_str(), nick); Alog() << Config.s_NickServ << ": " << u->nick << " set FORBID for nick " << nick; notice_lang(Config.s_NickServ, u, NICK_FORBID_SUCCEEDED, nick); @@ -97,6 +100,11 @@ class CommandNSForbid : public Command { syntax_error(Config.s_NickServ, u, "FORBID", Config.ForceForbidReason ? NICK_FORBID_SYNTAX_REASON : NICK_FORBID_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_FORBID); + } }; class NSForbid : public Module @@ -108,13 +116,7 @@ class NSForbid : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSForbid()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_FORBID); + this->AddCommand(NickServ, new CommandNSForbid()); } }; diff --git a/src/core/ns_getemail.c b/src/core/ns_getemail.cpp index 9c72ea023..c0a2980c5 100644 --- a/src/core/ns_getemail.c +++ b/src/core/ns_getemail.cpp @@ -29,29 +29,30 @@ class CommandNSGetEMail : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { ci::string email = params[0]; - int i, j = 0; - NickCore *nc; + int j = 0; Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETEMAIL on " << email; - for (i = 0; i < 1024; ++i) + + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (nc = nclists[i]; nc; nc = nc->next) + NickCore *nc = it->second; + + if (nc->email) { - if (nc->email) + if (nc->email == email) { - if (nc->email == email) - { - ++j; - notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_EMAILS_ARE, nc->display, email.c_str()); - } + ++j; + notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_EMAILS_ARE, nc->display, email.c_str()); } } } + if (j <= 0) { notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_NOT_USED, email.c_str()); return MOD_CONT; } + return MOD_CONT; } @@ -65,6 +66,11 @@ class CommandNSGetEMail : public Command { syntax_error(Config.s_NickServ, u, "GETMAIL", NICK_GETEMAIL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETEMAIL); + } }; class NSGetEMail : public Module @@ -76,13 +82,7 @@ class NSGetEMail : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSGetEMail()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETEMAIL); + this->AddCommand(NickServ, new CommandNSGetEMail()); } }; diff --git a/src/core/ns_getpass.c b/src/core/ns_getpass.cpp index 01ce31c90..cda008967 100644 --- a/src/core/ns_getpass.c +++ b/src/core/ns_getpass.cpp @@ -34,7 +34,7 @@ class CommandNSGetPass : public Command { Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETPASS on " << nick; if (Config.WallGetpass) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick); notice_lang(Config.s_NickServ, u, NICK_GETPASS_PASSCODE_IS, nick, nr->passcode.c_str()); } else @@ -50,7 +50,7 @@ class CommandNSGetPass : public Command { Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETPASS on " << nick; if (Config.WallGetpass) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick); notice_lang(Config.s_NickServ, u, NICK_GETPASS_PASSWORD_IS, nick, tmp_pass.c_str()); } else @@ -69,6 +69,11 @@ class CommandNSGetPass : public Command { syntax_error(Config.s_NickServ, u, "GETPASS", NICK_GETPASS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETPASS); + } }; class NSGetPass : public Module @@ -80,17 +85,11 @@ class NSGetPass : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSGetPass()); + this->AddCommand(NickServ, new CommandNSGetPass()); std::string tmp_pass = "plain:tmp"; if (enc_decrypt(tmp_pass, tmp_pass) == -1) throw ModuleException("Incompatible with the encryption module being used"); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETPASS); } }; diff --git a/src/core/ns_ghost.c b/src/core/ns_ghost.cpp index 41c0a68a4..1ae0a1946 100644 --- a/src/core/ns_ghost.c +++ b/src/core/ns_ghost.cpp @@ -82,6 +82,11 @@ class CommandNSGhost : public Command { syntax_error(Config.s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GHOST); + } }; class NSGhost : public Module @@ -93,13 +98,7 @@ class NSGhost : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSGhost()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GHOST); + this->AddCommand(NickServ, new CommandNSGhost()); } }; diff --git a/src/core/ns_group.c b/src/core/ns_group.cpp index 2aa47ac1f..ffb94296b 100644 --- a/src/core/ns_group.c +++ b/src/core/ns_group.cpp @@ -29,7 +29,7 @@ class CommandNSGroup : public Command std::string pass = params[1].c_str(); std::list<std::pair<std::string, std::string> >::iterator it; - if (Config.NSEmailReg && findrequestnick(u->nick.c_str())) + if (Config.NSEmailReg && findrequestnick(u->nick)) { notice_lang(Config.s_NickServ, u, NICK_REQUESTED); return MOD_CONT; @@ -51,9 +51,7 @@ class CommandNSGroup : public Command { for (it = Config.Opers.begin(); it != Config.Opers.end(); ++it) { - std::string nick = it->first; - - if (stristr(u->nick.c_str(), nick.c_str()) && !is_oper(u)) + if (!is_oper(u) && u->nick.find(it->first) != std::string::npos) { notice_lang(Config.s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); return MOD_CONT; @@ -82,7 +80,7 @@ class CommandNSGroup : public Command notice_lang(Config.s_NickServ, u, NICK_GROUP_SAME, target->nick); else if (na && na->nc != u->Account()) notice_lang(Config.s_NickServ, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ); - else if (Config.NSMaxAliases && (target->nc->aliases.count >= Config.NSMaxAliases) && !target->nc->IsServicesOper()) + else if (Config.NSMaxAliases && (target->nc->aliases.size() >= Config.NSMaxAliases) && !target->nc->IsServicesOper()) notice_lang(Config.s_NickServ, u, NICK_GROUP_TOO_MANY, target->nick, Config.s_NickServ, Config.s_NickServ); else if (enc_check_password(pass, target->nc->pass) != 1) { @@ -151,6 +149,82 @@ class CommandNSGroup : public Command { syntax_error(Config.s_NickServ, u, "GROUP", NICK_GROUP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GROUP); + } +}; + +class CommandNSUngroup : public Command +{ + public: + CommandNSUngroup() : Command("UNGROUP", 0, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + const char *nick = params.size() ? params[0].c_str() : NULL; + NickAlias *na = nick ? findnick(nick) : findnick(u->nick); + + if (u->Account()->aliases.size() == 1) + notice_lang(Config.s_NickServ, u, NICK_UNGROUP_ONE_NICK); + else if (!na) + notice_lang(Config.s_NickServ, u, NICK_X_NOT_REGISTERED, nick ? nick : u->nick.c_str()); + else if (na->nc != u->Account()) + notice_lang(Config.s_NickServ, u, NICK_UNGROUP_NOT_IN_GROUP, na->nick); + else + { + NickCore *oldcore = na->nc; + + std::list<NickAlias *>::iterator it = std::find(oldcore->aliases.begin(), oldcore->aliases.end(), na); + if (it != oldcore->aliases.end()) + { + oldcore->aliases.erase(it); + } + + if (!stricmp(oldcore->display, na->nick)) + { + change_core_display(oldcore); + } + + na->nc = new NickCore(na->nick); + na->nc->aliases.push_back(na); + + na->nc->pass = oldcore->pass; + if (oldcore->email) + na->nc->email = sstrdup(oldcore->email); + if (oldcore->greet) + na->nc->greet = sstrdup(oldcore->greet); + na->nc->icq = oldcore->icq; + if (oldcore->url) + na->nc->url = sstrdup(oldcore->url); + na->nc->language = oldcore->language; + + notice_lang(Config.s_NickServ, u, NICK_UNGROUP_SUCCESSFUL, na->nick, oldcore->display); + + User *user = finduser(na->nick); + if (user) + { + /* The user on the nick who was ungrouped may be identified to the old group, set -r */ + user->RemoveMode(NickServ, UMODE_REGISTERED); + } + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_NickServ, u, NICK_HELP_UNGROUP); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNGROUP); + } }; class CommandNSGList : public Command @@ -165,7 +239,6 @@ class CommandNSGList : public Command const char *nick = params.size() ? params[0].c_str() : NULL; NickCore *nc = u->Account(); - int i; if (nick && (stricmp(nick, u->nick.c_str()) && !u->Account()->IsServicesOper())) notice_lang(Config.s_NickServ, u, ACCESS_DENIED, Config.s_NickServ); @@ -179,21 +252,19 @@ class CommandNSGList : public Command int wont_expire; notice_lang(Config.s_NickServ, u, nick ? NICK_GLIST_HEADER_X : NICK_GLIST_HEADER, nc->display); - for (i = 0; i < nc->aliases.count; ++i) + for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it) { - NickAlias *na2 = static_cast<NickAlias *>(nc->aliases.list[i]); - if (na2->nc == nc) + NickAlias *na2 = *it; + + if (!(wont_expire = na2->HasFlag(NS_NO_EXPIRE))) { - if (!(wont_expire = na2->HasFlag(NS_NO_EXPIRE))) - { - expt = na2->last_seen + Config.NSExpire; - tm = localtime(&expt); - strftime_lang(buf, sizeof(buf), finduser(na2->nick), STRFTIME_DATE_TIME_FORMAT, tm); - } - notice_lang(Config.s_NickServ, u, u->Account()->IsServicesOper() && !wont_expire ? NICK_GLIST_REPLY_ADMIN : NICK_GLIST_REPLY, wont_expire ? '!' : ' ', na2->nick, buf); + expt = na2->last_seen + Config.NSExpire; + tm = localtime(&expt); + strftime_lang(buf, sizeof(buf), finduser(na2->nick), STRFTIME_DATE_TIME_FORMAT, tm); } + notice_lang(Config.s_NickServ, u, wont_expire ? NICK_GLIST_REPLY_NOEXPIRE : NICK_GLIST_REPLY, na2->nick, buf); } - notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.count); + notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.size()); } return MOD_CONT; } @@ -208,6 +279,11 @@ class CommandNSGList : public Command return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GLIST); + } }; class NSGroup : public Module @@ -219,15 +295,9 @@ class NSGroup : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSGroup()); - this->AddCommand(NICKSERV, new CommandNSGList()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GROUP); - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GLIST); + this->AddCommand(NickServ, new CommandNSGroup()); + this->AddCommand(NickServ, new CommandNSUngroup()); + this->AddCommand(NickServ, new CommandNSGList()); } }; diff --git a/src/core/ns_help.c b/src/core/ns_help.cpp index a2485c6dc..a9b40592f 100644 --- a/src/core/ns_help.c +++ b/src/core/ns_help.cpp @@ -34,7 +34,7 @@ class CommandNSHelp : public Command u->SendMessage(Config.s_NickServ, " %2d) %s", i + 1, langnames[langlist[i]]); } else - mod_help_cmd(Config.s_NickServ, u, NICKSERV, cmd.c_str()); + mod_help_cmd(NickServ, u, cmd.c_str()); return MOD_CONT; } @@ -42,7 +42,8 @@ class CommandNSHelp : public Command void OnSyntaxError(User *u, const ci::string &subcommand) { notice_help(Config.s_NickServ, u, NICK_HELP); - FOREACH_MOD(I_OnNickServHelp, OnNickServHelp(u)); + for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it) + it->second->OnServHelp(u); if (u->Account() && u->Account()->IsServicesOper()) notice_help(Config.s_NickServ, u, NICK_SERVADMIN_HELP); if (Config.NSExpire >= 86400) @@ -60,7 +61,7 @@ class NSHelp : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSHelp()); + this->AddCommand(NickServ, new CommandNSHelp()); } }; diff --git a/src/core/ns_identify.c b/src/core/ns_identify.cpp index 866497fc0..2f02cac81 100644 --- a/src/core/ns_identify.c +++ b/src/core/ns_identify.cpp @@ -17,7 +17,7 @@ class CommandNSIdentify : public Command { public: - CommandNSIdentify(const std::string &cname) : Command(cname, 1, 1) + CommandNSIdentify(const ci::string &cname) : Command(cname, 1, 1) { this->SetFlag(CFLAG_ALLOW_UNREGISTERED); } @@ -29,9 +29,9 @@ class CommandNSIdentify : public Command NickRequest *nr; int res; - if (!(na = findnick(u->nick.c_str()))) + if (!(na = findnick(u->nick))) { - if ((nr = findrequestnick(u->nick.c_str()))) + if ((nr = findrequestnick(u->nick))) notice_lang(Config.s_NickServ, u, NICK_IS_PREREG); else notice_lang(Config.s_NickServ, u, NICK_NOT_REGISTERED); @@ -104,6 +104,12 @@ class CommandNSIdentify : public Command { syntax_error(Config.s_NickServ, u, "IDENTIFY", NICK_IDENTIFY_SYNTAX); } + + void OnServHelp(User *u) + { + if (this->name == "IDENTIFY") + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_IDENTIFY); + } }; class NSIdentify : public Module @@ -115,14 +121,8 @@ class NSIdentify : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSIdentify("IDENTIFY")); - this->AddCommand(NICKSERV, new CommandNSIdentify("ID")); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_IDENTIFY); + this->AddCommand(NickServ, new CommandNSIdentify("IDENTIFY")); + this->AddCommand(NickServ, new CommandNSIdentify("ID")); } }; diff --git a/src/core/ns_info.c b/src/core/ns_info.cpp index 0635e52df..e5a4d5e9e 100644 --- a/src/core/ns_info.c +++ b/src/core/ns_info.cpp @@ -79,19 +79,19 @@ class CommandNSInfo : public Command { struct tm *tm; char buf[BUFSIZE]; - int nick_online = 0; - int show_hidden = 0; + bool nick_online = false, show_hidden = false; time_t expt; + bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex"); /* Is the real owner of the nick we're looking up online? -TheShadow */ User *u2 = finduser(na->nick); if (u2 && u2->Account() == na->nc) - nick_online = 1; + nick_online = true; /* Only show hidden fields to owner and sadmins and only when the ALL * parameter is used. -TheShadow */ - if (!param.empty() && param == "ALL" && u->Account() && (na->nc == u->Account() || u->Account()->IsServicesOper())) - show_hidden = 1; + if (!param.empty() && param == "ALL" && u->Account() && (na->nc == u->Account() || has_auspex)) + show_hidden = true; notice_lang(Config.s_NickServ, u, NICK_INFO_REALNAME, na->nick, na->last_realname); @@ -100,7 +100,6 @@ class CommandNSInfo : public Command if (show_hidden || (!(na->nc->HasFlag(NI_HIDE_STATUS)))) { notice_lang(Config.s_NickServ, u, NICK_INFO_SERVICES_OPERTYPE, na->nick, na->nc->ot->GetName().c_str()); - } } @@ -111,7 +110,8 @@ class CommandNSInfo : public Command else notice_lang(Config.s_NickServ, u, NICK_INFO_ADDRESS_ONLINE_NOHOST, na->nick); } - else { + else + { if (show_hidden || !(na->nc->HasFlag(NI_HIDE_MASK))) notice_lang(Config.s_NickServ, u, NICK_INFO_ADDRESS, na->last_usermask); } @@ -171,17 +171,16 @@ class CommandNSInfo : public Command notice_lang(Config.s_NickServ, u, NICK_INFO_NO_EXPIRE); else { - if (u->Account()->IsServicesOper()) - { - expt = na->last_seen + Config.NSExpire; - tm = localtime(&expt); - strftime_lang(buf, sizeof(buf), finduser(na->nick), STRFTIME_DATE_TIME_FORMAT, tm); - notice_lang(Config.s_NickServ, u, NICK_INFO_EXPIRE, buf); - } + expt = na->last_seen + Config.NSExpire; + tm = localtime(&expt); + strftime_lang(buf, sizeof(buf), finduser(na->nick), STRFTIME_DATE_TIME_FORMAT, tm); + notice_lang(Config.s_NickServ, u, NICK_INFO_EXPIRE, buf); } } - if (!show_hidden && u->Account() && (na->nc == u->Account() || u->Account()->IsServicesOper())) + FOREACH_MOD(I_OnNickInfo, OnNickInfo(u, na, show_hidden)); + + if (!show_hidden && u->Account() && (na->nc == u->Account() || has_auspex)) notice_lang(Config.s_NickServ, u, NICK_INFO_FOR_MORE, Config.s_NickServ, na->nick); } return MOD_CONT; @@ -190,7 +189,7 @@ class CommandNSInfo : public Command bool OnHelp(User *u, const ci::string &subcommand) { notice_help(Config.s_NickServ, u, NICK_HELP_INFO); - if (u->Account() && u->Account()->IsServicesOper()) + if (u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex")) notice_help(Config.s_NickServ, u, NICK_SERVADMIN_HELP_INFO); return true; @@ -200,6 +199,11 @@ class CommandNSInfo : public Command { syntax_error(Config.s_NickServ, u, "INFO", NICK_INFO_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_INFO); + } }; class NSInfo : public Module @@ -211,13 +215,7 @@ class NSInfo : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSInfo()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_INFO); + this->AddCommand(NickServ, new CommandNSInfo()); } }; diff --git a/src/core/ns_list.c b/src/core/ns_list.cpp index 195763037..7b9419a14 100644 --- a/src/core/ns_list.c +++ b/src/core/ns_list.cpp @@ -38,12 +38,10 @@ class CommandNSList : public Command * UPDATE: SUSPENDED keyword is now accepted as well. */ const char *pattern = params[0].c_str(); - NickAlias *na; NickCore *mync; - unsigned nnicks, i; + unsigned nnicks; char buf[BUFSIZE]; bool is_servadmin = u->Account()->IsServicesOper(); - NickRequest *nr = NULL; char noexpire_char = ' '; int count = 0, from = 0, to = 0, tofree = 0; char *tmp = NULL; @@ -123,46 +121,45 @@ class CommandNSList : public Command notice_lang(Config.s_NickServ, u, NICK_LIST_HEADER, pattern); if (!unconfirmed) { - for (i = 0; i < 1024; ++i) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (na = nalists[i]; na; na = na->next) + NickAlias *na = it->second; + + /* Don't show private and forbidden nicks to non-services admins. */ + if ((na->HasFlag(NS_FORBIDDEN)) && !is_servadmin) + continue; + if ((na->nc->HasFlag(NI_PRIVATE)) && !is_servadmin && na->nc != mync) + continue; + if (forbidden && !na->HasFlag(NS_FORBIDDEN)) + continue; + else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE)) + continue; + else if (suspended && !na->nc->HasFlag(NI_SUSPENDED)) + continue; + + /* We no longer compare the pattern against the output buffer. + * Instead we build a nice nick!user@host buffer to compare. + * The output is then generated separately. -TheShadow */ + snprintf(buf, sizeof(buf), "%s!%s", na->nick, na->last_usermask && !(na->HasFlag(NS_FORBIDDEN)) ? na->last_usermask : "*@*"); + if (!stricmp(pattern, na->nick) || Anope::Match(buf, pattern, false)) { - /* Don't show private and forbidden nicks to non-services admins. */ - if ((na->HasFlag(NS_FORBIDDEN)) && !is_servadmin) - continue; - if ((na->nc->HasFlag(NI_PRIVATE)) && !is_servadmin && na->nc != mync) - continue; - if (forbidden && !na->HasFlag(NS_FORBIDDEN)) - continue; - else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE)) - continue; - else if (suspended && !na->nc->HasFlag(NI_SUSPENDED)) - continue; - - /* We no longer compare the pattern against the output buffer. - * Instead we build a nice nick!user@host buffer to compare. - * The output is then generated separately. -TheShadow */ - snprintf(buf, sizeof(buf), "%s!%s", na->nick, na->last_usermask && !(na->HasFlag(NS_FORBIDDEN)) ? na->last_usermask : "*@*"); - if (!stricmp(pattern, na->nick) || Anope::Match(buf, pattern, false)) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config.NSListMax) { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config.NSListMax) - { - if (is_servadmin && (na->HasFlag(NS_NO_EXPIRE))) - noexpire_char = '!'; - else - noexpire_char = ' '; - if ((na->nc->HasFlag(NI_HIDE_MASK)) && !is_servadmin && na->nc != mync) - snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick); - else if (na->HasFlag(NS_FORBIDDEN)) - snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick); - else if (na->nc->HasFlag(NI_SUSPENDED)) - snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick); - else - snprintf(buf, sizeof(buf), "%-20s %s", na->nick, na->last_usermask); - u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf); - } - ++count; + if (is_servadmin && (na->HasFlag(NS_NO_EXPIRE))) + noexpire_char = '!'; + else + noexpire_char = ' '; + if ((na->nc->HasFlag(NI_HIDE_MASK)) && !is_servadmin && na->nc != mync) + snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick); + else if (na->HasFlag(NS_FORBIDDEN)) + snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick); + else if (na->nc->HasFlag(NI_SUSPENDED)) + snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick); + else + snprintf(buf, sizeof(buf), "%-20s %s", na->nick, na->last_usermask); + u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf); } + ++count; } } } @@ -170,18 +167,18 @@ class CommandNSList : public Command if (unconfirmed || is_servadmin) { noexpire_char = ' '; - for (i = 0; i < 1024; ++i) + + for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it) { - for (nr = nrlists[i]; nr; nr = nr->next) + NickRequest *nr = it->second; + + snprintf(buf, sizeof(buf), "%s!*@*", nr->nick); + if (!stricmp(pattern, nr->nick) || Anope::Match(buf, pattern, false)) { - snprintf(buf, sizeof(buf), "%s!*@*", nr->nick); - if (!stricmp(pattern, nr->nick) || Anope::Match(buf, pattern, false)) + if (++nnicks <= Config.NSListMax) { - if (++nnicks <= Config.NSListMax) - { - snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick); - u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf); - } + snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick); + u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf); } } } @@ -209,6 +206,11 @@ class CommandNSList : public Command else syntax_error(Config.s_NickServ, u, "LIST", NICK_LIST_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LIST); + } }; class NSList : public Module @@ -220,13 +222,7 @@ class NSList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSList()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LIST); + this->AddCommand(NickServ, new CommandNSList()); } }; diff --git a/src/core/ns_logout.c b/src/core/ns_logout.cpp index 373dbabbd..c3d5696f2 100644 --- a/src/core/ns_logout.c +++ b/src/core/ns_logout.cpp @@ -77,6 +77,11 @@ class CommandNSLogout : public Command { syntax_error(Config.s_NickServ, u, "LOGOUT", NICK_LOGOUT_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LOGOUT); + } }; class NSLogout : public Module @@ -88,13 +93,7 @@ class NSLogout : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSLogout()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LOGOUT); + this->AddCommand(NickServ, new CommandNSLogout()); } }; diff --git a/src/core/ns_recover.c b/src/core/ns_recover.cpp index 7484da87c..501c06642 100644 --- a/src/core/ns_recover.c +++ b/src/core/ns_recover.cpp @@ -103,6 +103,11 @@ class CommandNSRecover : public Command { syntax_error(Config.s_NickServ, u, "RECOVER", NICK_RECOVER_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RECOVER); + } }; class NSRecover : public Module @@ -114,13 +119,7 @@ class NSRecover : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSRecover()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RECOVER); + this->AddCommand(NickServ, new CommandNSRecover()); } }; diff --git a/src/core/ns_register.c b/src/core/ns_register.cpp index 4a9bfb6fe..f8bf1691f 100644 --- a/src/core/ns_register.c +++ b/src/core/ns_register.cpp @@ -14,7 +14,7 @@ #include "module.h" -int do_sendregmail(User *u, NickRequest *nr); +static bool SendRegmail(User *u, NickRequest *nr); class CommandNSConfirm : public Command { @@ -94,10 +94,9 @@ class CommandNSConfirm : public Command CommandReturn DoConfirm(User *u, const std::vector<ci::string> ¶ms) { - NickRequest *nr = NULL; std::string passcode = !params.empty() ? params[0].c_str() : ""; - nr = findrequestnick(u->nick.c_str()); + NickRequest *nr = findrequestnick(u->nick); if (Config.NSEmailReg) { @@ -113,7 +112,7 @@ class CommandNSConfirm : public Command { /* If an admin, their nick is obviously already regged, so look at the passcode to get the nick of the user they are trying to validate, and push that user through regardless of passcode */ - nr = findrequestnick(passcode.c_str()); + nr = findrequestnick(passcode); if (nr) { ActuallyConfirmNick(u, nr, true); @@ -143,7 +142,7 @@ class CommandNSConfirm : public Command } public: - CommandNSConfirm(const std::string &cmdn, int min, int max) : Command(cmdn, min, max) + CommandNSConfirm(const ci::string &cmdn, int min, int max) : Command(cmdn, min, max) { this->SetFlag(CFLAG_ALLOW_UNREGISTERED); } @@ -165,6 +164,11 @@ class CommandNSConfirm : public Command { notice_lang(Config.s_NickServ, u, NICK_CONFIRM_INVALID); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_CONFIRM); + } }; class CommandNSRegister : public CommandNSConfirm @@ -206,7 +210,7 @@ class CommandNSRegister : public CommandNSConfirm return MOD_CONT; } - if ((anr = findrequestnick(u->nick.c_str()))) + if ((anr = findrequestnick(u->nick))) { notice_lang(Config.s_NickServ, u, NICK_REQUESTED); return MOD_CONT; @@ -247,7 +251,7 @@ class CommandNSRegister : public CommandNSConfirm this->OnSyntaxError(u, ""); else if (time(NULL) < u->lastnickreg + Config.NSRegDelay) notice_lang(Config.s_NickServ, u, NICK_REG_PLEASE_WAIT, (u->lastnickreg + Config.NSRegDelay) - time(NULL)); - else if ((na = findnick(u->nick.c_str()))) + else if ((na = findnick(u->nick))) { /* i.e. there's already such a nick regged */ if (na->HasFlag(NS_FORBIDDEN)) @@ -279,7 +283,7 @@ class CommandNSRegister : public CommandNSConfirm FOREACH_MOD(I_OnMakeNickRequest, OnMakeNickRequest(nr)); if (Config.NSEmailReg) { - if (!do_sendregmail(u, nr)) + if (SendRegmail(u, nr)) { notice_lang(Config.s_NickServ, u, NICK_ENTER_REG_CODE, email, Config.s_NickServ); Alog() << Config.s_NickServ << ": sent registration verification code to " << nr->email; @@ -315,6 +319,11 @@ class CommandNSRegister : public CommandNSConfirm else syntax_error(Config.s_NickServ, u, "REGISTER", NICK_REGISTER_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_REGISTER); + } }; class CommandNSResend : public Command @@ -330,14 +339,14 @@ class CommandNSResend : public Command NickRequest *nr = NULL; if (Config.NSEmailReg) { - if ((nr = findrequestnick(u->nick.c_str()))) + if ((nr = findrequestnick(u->nick))) { if (time(NULL) < nr->lastmail + Config.NSResendDelay) { notice_lang(Config.s_NickServ, u, MAIL_LATER); return MOD_CONT; } - if (!do_sendregmail(u, nr)) + if (!SendRegmail(u, nr)) { nr->lastmail = time(NULL); notice_lang(Config.s_NickServ, u, NICK_REG_RESENT, nr->email); @@ -358,6 +367,11 @@ class CommandNSResend : public Command notice_help(Config.s_NickServ, u, NICK_HELP_RESEND); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESEND); + } }; class NSRegister : public Module @@ -369,50 +383,20 @@ class NSRegister : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSRegister()); - this->AddCommand(NICKSERV, new CommandNSConfirm("CONFIRM", 1, 1)); - this->AddCommand(NICKSERV, new CommandNSResend()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_REGISTER); - if (Config.NSEmailReg) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_CONFIRM); - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESEND); - } + this->AddCommand(NickServ, new CommandNSRegister()); + this->AddCommand(NickServ, new CommandNSConfirm("CONFIRM", 1, 1)); + this->AddCommand(NickServ, new CommandNSResend()); } }; -/*************************************************************************/ - -int do_sendregmail(User *u, NickRequest *nr) +static bool SendRegmail(User *u, NickRequest *nr) { - MailInfo *mail = NULL; - char buf[BUFSIZE]; - - if (!nr && !u) - return -1; - snprintf(buf, sizeof(buf), getstring(NICK_REG_MAIL_SUBJECT), nr->nick); - mail = MailRegBegin(u, nr, buf, Config.s_NickServ); - if (!mail) - return -1; - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_HEAD)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_1), nr->nick); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_2), Config.s_NickServ, nr->passcode.c_str()); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_4)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_5), Config.NetworkName); - fprintf(mail->pipe, "\n.\n"); - MailEnd(mail); - return 0; + char subject[BUFSIZE], message[BUFSIZE]; + + snprintf(subject, sizeof(subject), getstring(NICK_REG_MAIL_SUBJECT), nr->nick); + snprintf(message, sizeof(message), getstring(NICK_REG_MAIL), nr->nick, Config.NetworkName, Config.s_NickServ, nr->passcode.c_str(), Config.NetworkName); + + return Mail(u, nr, Config.s_NickServ, subject, message); } MODULE_INIT(NSRegister) diff --git a/src/core/ns_release.c b/src/core/ns_release.cpp index 0855bc46d..7efcdae88 100644 --- a/src/core/ns_release.c +++ b/src/core/ns_release.cpp @@ -85,6 +85,11 @@ class CommandNSRelease : public Command { syntax_error(Config.s_NickServ, u, "RELEASE", NICK_RELEASE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RELEASE); + } }; class NSRelease : public Module @@ -96,13 +101,7 @@ class NSRelease : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSRelease()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RELEASE); + this->AddCommand(NickServ, new CommandNSRelease()); } }; diff --git a/src/core/ns_resetpass.c b/src/core/ns_resetpass.cpp index c47fa0308..be14caa08 100644 --- a/src/core/ns_resetpass.c +++ b/src/core/ns_resetpass.cpp @@ -14,6 +14,8 @@ #include "module.h" +static bool SendResetEmail(User *u, NickAlias *na); + class CommandNSResetPass : public Command { public: @@ -27,47 +29,17 @@ class CommandNSResetPass : public Command if (Config.RestrictMail && !u->Account()->HasCommand("nickserv/resetpass")) notice_lang(Config.s_NickServ, u, ACCESS_DENIED); - if (!(na = findnick(params[0].c_str()))) + if (!(na = findnick(params[0]))) notice_lang(Config.s_NickServ, u, NICK_X_NOT_REGISTERED, params[0].c_str()); else if (na->HasFlag(NS_FORBIDDEN)) notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); else { - char buf[BUFSIZE], message[BUFSIZE]; - snprintf(buf, sizeof(buf), getstring(na, NICK_RESETPASS_SUBJECT), na->nick); - - MailInfo *mail = MailBegin(u, na->nc, buf, Config.s_NickServ); - if (!mail) - return MOD_CONT; - - char passcode[20]; - int min = 1, max = 62; - int chars[] = { - ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - - int idx; - for (idx = 0; idx < 20; ++idx) - passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; - passcode[idx] = '\0'; - - snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName); - fprintf(mail->pipe, "%s", message); - fprintf(mail->pipe, "\n.\n"); - MailEnd(mail); - - na->nc->Shrink("ns_resetpass_code"); - na->nc->Shrink("ns_resetpass_time"); - - na->nc->Extend("ns_resetpass_code", new ExtensibleItemPointerArray<char>(sstrdup(passcode))); - na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL))); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")"; - notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick); + if (SendResetEmail(u, na)) + { + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")"; + notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick); + } } return MOD_CONT; @@ -83,6 +55,11 @@ class CommandNSResetPass : public Command { syntax_error(Config.s_NickServ, u, "RESETPASS", NICK_RESETPASS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESETPASS); + } }; class NSResetPass : public Module @@ -97,27 +74,20 @@ class NSResetPass : public Module if (!Config.UseMail) throw ModuleException("Not using mail."); - this->AddCommand(NICKSERV, new CommandNSResetPass()); - - Implementation i[] = { I_OnNickServHelp, I_OnPreCommand }; - ModuleManager::Attach(i, this, 2); - } + this->AddCommand(NickServ, new CommandNSResetPass()); - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESETPASS); + ModuleManager::Attach(I_OnPreCommand, this); } EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) { - time_t t; - char *c; - if (service == Config.s_NickServ && command == "CONFIRM" && !params.empty()) { NickAlias *na = findnick(u->nick); - if (na && na->nc->GetExtArray("ns_resetpass_code", c) && na->nc->GetExtRegular<time_t>("ns_resetpass_time", t)) + time_t t; + std::string c; + if (na && na->nc->GetExtRegular("ns_resetpass_code", c) && na->nc->GetExtRegular("ns_resetpass_time", t)) { if (t < time(NULL) - 3600) { @@ -167,4 +137,35 @@ class NSResetPass : public Module } }; +static bool SendResetEmail(User *u, NickAlias *na) +{ + char subject[BUFSIZE], message[BUFSIZE], passcode[20]; + + snprintf(subject, sizeof(subject), getstring(na, NICK_RESETPASS_SUBJECT), na->nick); + + int min = 1, max = 62; + int chars[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + }; + + int idx; + for (idx = 0; idx < 20; ++idx) + passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; + passcode[idx] = '\0'; + + snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName); + + na->nc->Shrink("ns_resetpass_code"); + na->nc->Shrink("ns_resetpass_time"); + + na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<std::string>(passcode)); + na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL))); + + return Mail(u, na->nc, Config.s_NickServ, subject, message); +} + MODULE_INIT(NSResetPass) diff --git a/src/core/ns_saset.c b/src/core/ns_saset.c deleted file mode 100644 index 6978ba356..000000000 --- a/src/core/ns_saset.c +++ /dev/null @@ -1,599 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -class CommandNSSASet : public Command -{ -private: - CommandReturn DoSetDisplay(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - int i; - NickAlias *na; - - if (param.empty()) - { - this->OnSyntaxError(u, "DISPLAY"); - return MOD_CONT; - } - - /* First check whether param is a valid nick of the group */ - for (i = 0; i < nc->aliases.count; ++i) - { - na = static_cast<NickAlias *>(nc->aliases.list[i]); - if (na->nick == param) - { - param = na->nick; /* Because case may differ */ - break; - } - } - - if (i == nc->aliases.count) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display); - return MOD_CONT; - } - - change_core_display(nc, param.c_str()); - notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_CHANGED, nc->display); - return MOD_CONT; - } - - CommandReturn DoSetPassword(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - std::string buf, tmp_pass; - - if (param.empty()) - { - this->OnSyntaxError(u, "PASSWORD"); - return MOD_CONT; - } - - int len = param.size(); - - if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper()) - { - notice_lang(Config.s_NickServ, u, ACCESS_DENIED); - return MOD_CONT; - } - else if (nc->display == param || (Config.StrictPasswords && len < 5)) - { - notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD); - return MOD_CONT; - } - else if (len > Config.PassLen) - { - notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG); - return MOD_CONT; - } - buf = param.c_str(); /* conversion from ci::string to std::string */ - if (enc_encrypt(buf, nc->pass)) - { - Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (set)"; - notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_FAILED, nc->display); - return MOD_CONT; - } - - if (enc_decrypt(nc->pass, tmp_pass) == 1) - notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED_TO, nc->display, tmp_pass.c_str()); - else - notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED, nc->display); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET PASSWORD on " << nc->display << " (e-mail: "<< (nc->email ? nc->email : "none") << ")"; - if (Config.WallSetpass) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used SASET PASSWORD on \2%s\2", u->nick.c_str(), nc->display); - return MOD_CONT; - } - - CommandReturn DoSetUrl(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 2 ? params[2].c_str() : NULL; - - if (nc->url) - delete [] nc->url; - - if (param) - { - nc->url = sstrdup(param); - notice_lang(Config.s_NickServ, u, NICK_SASET_URL_CHANGED, nc->display, param); - } - else - { - nc->url = NULL; - notice_lang(Config.s_NickServ, u, NICK_SASET_URL_UNSET, nc->display); - } - return MOD_CONT; - } - - CommandReturn DoSetEmail(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 2 ? params[2].c_str() : NULL; - - if (!param && Config.NSForceEmail) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET_IMPOSSIBLE); - return MOD_CONT; - } - else if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper()) - { - notice_lang(Config.s_NickServ, u, ACCESS_DENIED); - return MOD_CONT; - } - else if (param && !MailValidate(param)) - { - notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param); - return MOD_CONT; - } - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET EMAIL on " << nc->display << " (e-mail: " << (nc->email ? nc->email : "none") << ")"; - - if (nc->email) - delete [] nc->email; - - if (param) - { - nc->email = sstrdup(param); - notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_CHANGED, nc->display, param); - } - else - { - nc->email = NULL; - notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET, nc->display); - } - return MOD_CONT; - } - - CommandReturn DoSetICQ(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 2 ? params[2].c_str() : NULL; - - if (param) - { - int32 tmp = atol(param); - if (!tmp) - notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_INVALID, param); - else - { - nc->icq = tmp; - notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_CHANGED, nc->display, param); - } - } - else - { - nc->icq = 0; - notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_UNSET, nc->display); - } - return MOD_CONT; - } - - CommandReturn DoSetGreet(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 2 ? params[2].c_str() : NULL; - - if (nc->greet) - delete [] nc->greet; - - if (param) - { - char buf[BUFSIZE]; - const char *rest = params.size() > 3 ? params[3].c_str() : NULL; - - snprintf(buf, sizeof(buf), "%s%s%s", param, rest ? " " : "", rest ? rest : ""); - - nc->greet = sstrdup(buf); - notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_CHANGED, nc->display, buf); - } - else - { - nc->greet = NULL; - notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_UNSET, nc->display); - } - return MOD_CONT; - } - - CommandReturn DoSetKill(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "KILL"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_ON, nc->display); - } - else if (param == "QUICK") - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_QUICK, nc->display); - } - else if (param == "IMMED") - { - if (Config.NSAllowKillImmed) - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_IMMED); - nc->UnsetFlag(NI_KILL_QUICK); - notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED, nc->display); - } - else - notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED_DISABLED); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_OFF, nc->display); - } - else - syntax_error(Config.s_NickServ, u, "SASET KILL", Config.NSAllowKillImmed ? NICK_SASET_KILL_IMMED_SYNTAX : NICK_SASET_KILL_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetSecure(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "SECURE"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_SECURE); - notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_ON, nc->display); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_SECURE); - notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_OFF, nc->display); - } - else - syntax_error(Config.s_NickServ, u, "SASET SECURE", NICK_SASET_SECURE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetPrivate(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "PRIVATE"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_PRIVATE); - notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_ON, nc->display); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_PRIVATE); - notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_OFF, nc->display); - } - else - syntax_error(Config.s_NickServ, u, "SASET PRIVATE", NICK_SASET_PRIVATE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetMsg(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "MSG"); - return MOD_CONT; - } - - if (!Config.UsePrivmsg) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_OPTION_DISABLED, "MSG"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_MSG); - notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_ON, nc->display); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_MSG); - notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_OFF, nc->display); - } - else - syntax_error(Config.s_NickServ, u, "SASET MSG", NICK_SASET_MSG_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetHide(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "HIDE"); - return MOD_CONT; - } - - int onmsg, offmsg; - NickCoreFlag flag; - - if (param == "EMAIL") - { - flag = NI_HIDE_EMAIL; - onmsg = NICK_SASET_HIDE_EMAIL_ON; - offmsg = NICK_SASET_HIDE_EMAIL_OFF; - } - else if (param == "USERMASK") - { - flag = NI_HIDE_MASK; - onmsg = NICK_SASET_HIDE_MASK_ON; - offmsg = NICK_SASET_HIDE_MASK_OFF; - } - else if (param == "STATUS") - { - flag = NI_HIDE_STATUS; - onmsg = NICK_SASET_HIDE_STATUS_ON; - offmsg = NICK_SASET_HIDE_STATUS_OFF; - } - else if (param == "QUIT") - { - flag = NI_HIDE_QUIT; - onmsg = NICK_SASET_HIDE_QUIT_ON; - offmsg = NICK_SASET_HIDE_QUIT_OFF; - } - else - { - syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX); - return MOD_CONT; - } - - param = params.size() > 3 ? params[3] : ""; - if (param.empty()) - syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX); - else if (param == "ON") - { - nc->SetFlag(flag); - notice_lang(Config.s_NickServ, u, onmsg, nc->display, Config.s_NickServ); - } - else if (param == "OFF") - { - nc->UnsetFlag(flag); - notice_lang(Config.s_NickServ, u, offmsg, nc->display, Config.s_NickServ); - } - else - syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetNoExpire(User *u, const std::vector<ci::string> ¶ms, NickAlias *na) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX); - return MOD_CONT; - } - - if (param == "ON") - { - na->SetFlag(NS_NO_EXPIRE); - notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_ON, na->nick); - } - else if (param == "OFF") - { - na->UnsetFlag(NS_NO_EXPIRE); - notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_OFF, na->nick); - } - else - syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetAutoOP(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 2 ? params[2] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "AUTOOP"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_AUTOOP); - notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_ON, nc->display); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_AUTOOP); - notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_OFF, nc->display); - } - else - syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SASET_AUTOOP_SYNTAX); - - return MOD_CONT; - } - - CommandReturn DoSetLanguage(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 2 ? params[2].c_str() : NULL; - - if (!param) - { - this->OnSyntaxError(u, "LANGUAGE"); - return MOD_CONT; - } - - int langnum; - - if (param[strspn(param, "0123456789")]) /* i.e. not a number */ - { - syntax_error(Config.s_NickServ, u, "SASET LANGUAGE", NICK_SASET_LANGUAGE_SYNTAX); - return MOD_CONT; - } - langnum = atoi(param) - 1; - if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ); - return MOD_CONT; - } - nc->language = langlist[langnum]; - notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_CHANGED); - - return MOD_CONT; - } -public: - CommandNSSASet() : Command("SASET", 2, 4, "nickserv/saset") - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - const char *nick = params[0].c_str(); - ci::string cmd = params[1]; - - NickAlias *na; - - if (readonly) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_DISABLED); - return MOD_CONT; - } - if (!(na = findnick(nick))) - { - notice_lang(Config.s_NickServ, u, NICK_SASET_BAD_NICK, nick); - return MOD_CONT; - } - - if (na->HasFlag(NS_FORBIDDEN)) - notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); - else if (na->nc->HasFlag(NI_SUSPENDED)) - notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, na->nick); - else if (cmd == "DISPLAY") - return this->DoSetDisplay(u, params, na->nc); - else if (cmd == "PASSWORD") - return this->DoSetPassword(u, params, na->nc); - else if (cmd == "URL") - return this->DoSetUrl(u, params, na->nc); - else if (cmd == "EMAIL") - return this->DoSetEmail(u, params, na->nc); - else if (cmd == "ICQ") - return this->DoSetICQ(u, params, na->nc); - else if (cmd == "GREET") - return this->DoSetGreet(u, params, na->nc); - else if (cmd == "KILL") - return this->DoSetKill(u, params, na->nc); - else if (cmd == "SECURE") - return this->DoSetSecure(u, params, na->nc); - else if (cmd == "PRIVATE") - return this->DoSetPrivate(u, params, na->nc); - else if (cmd == "MSG") - return this->DoSetMsg(u, params, na->nc); - else if (cmd == "HIDE") - return this->DoSetHide(u, params, na->nc); - else if (cmd == "NOEXPIRE") - return this->DoSetNoExpire(u, params, na); - else if (cmd == "AUTOOP") - return this->DoSetAutoOP(u, params, na->nc); - else if (cmd == "LANGUAGE") - return this->DoSetLanguage(u, params, na->nc); - else - notice_lang(Config.s_NickServ, u, NICK_SASET_UNKNOWN_OPTION, cmd.c_str()); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - if (subcommand.empty()) - notice_help(Config.s_NickServ, u, NICK_HELP_SASET); - else if (subcommand == "DISPLAY") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_DISPLAY); - else if (subcommand == "PASSWORD") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PASSWORD); - else if (subcommand == "URL") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_URL); - else if (subcommand == "EMAIL") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_EMAIL); - else if (subcommand == "ICQ") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_ICQ); - else if (subcommand == "GREET") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_GREET); - else if (subcommand == "KILL") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_KILL); - else if (subcommand == "SECURE") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_SECURE); - else if (subcommand == "PRIVATE") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PRIVATE); - else if (subcommand == "MSG") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_MSG); - else if (subcommand == "HIDE") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HIDE); - else if (subcommand == "NOEXPIRE") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_NOEXPIRE); - else if (subcommand == "AUTOOP") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_AUTOOP); - else if (subcommand == "LANGUAGE") - notice_help(Config.s_NickServ, u, NICK_HELP_SASET_LANGUAGE); - else - return false; - - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX); - } -}; - -class NSSASet : public Module -{ -public: - NSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(NICKSERV, new CommandNSSASet()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET); - } -}; - -MODULE_INIT(NSSASet) diff --git a/src/core/ns_saset.cpp b/src/core/ns_saset.cpp new file mode 100644 index 000000000..ccc6be928 --- /dev/null +++ b/src/core/ns_saset.cpp @@ -0,0 +1,255 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSASet : public Command +{ + std::map<ci::string, Command *> subcommands; + public: + CommandNSSASet(const ci::string &cname) : Command(cname, 2, 4) + { + } + + ~CommandNSSASet() + { + for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + { + delete it->second; + } + this->subcommands.clear(); + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + const char *nick = params[0].c_str(); + ci::string cmd = params[1]; + + if (readonly) + { + notice_lang(Config.s_NickServ, u, NICK_SASET_DISABLED); + return MOD_CONT; + } + + NickAlias *na = findnick(nick); + if (!na) + notice_lang(Config.s_NickServ, u, NICK_SASET_BAD_NICK, nick); + else if (na->HasFlag(NS_FORBIDDEN)) + notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); + else if (na->nc->HasFlag(NI_SUSPENDED)) + notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, na->nick); + else + { + Command *c = this->FindCommand(params[1]); + + if (c) + { + ci::string cmdparams = na->nc->display; + for (std::vector<ci::string>::const_iterator it = params.begin() + 1; it != params.end(); ++it) + cmdparams += " " + *it; + mod_run_cmd(NickServ, u, c, params[1], cmdparams); + } + else + { + notice_lang(Config.s_NickServ, u, NICK_SASET_UNKNOWN_OPTION, cmd.c_str()); + } + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + if (subcommand.empty()) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HEAD); + for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + it->second->OnServHelp(u); + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_TAIL); + return true; + } + else + { + Command *c = this->FindCommand(subcommand); + + if (c) + { + return c->OnHelp(u, subcommand); + } + } + + return false; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET); + } + + bool AddSubcommand(Command *c) + { + return this->subcommands.insert(std::make_pair(c->name, c)).second; + } + + bool DelSubcommand(const ci::string &command) + { + return this->subcommands.erase(command); + } + + Command *FindCommand(const ci::string &subcommand) + { + std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand); + + if (it != this->subcommands.end()) + { + return it->second; + } + + return NULL; + } +}; + +class CommandNSSASetDisplay : public Command +{ + public: + CommandNSSASetDisplay(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/display") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + NickAlias *na = findnick(params[1]); + if (!na || na->nc != nc) + { + notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display); + return MOD_CONT; + } + + change_core_display(nc, params[1].c_str()); + notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_CHANGED, nc->display); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_DISPLAY); + return true; + } + + void OnSyntaxError(User *u) + { + // XXX + syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_DISPLAY); + } +}; + +class CommandNSSASetPassword : public Command +{ + public: + CommandNSSASetPassword(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/password") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + size_t len = params[1].size(); + + if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper()) + { + notice_lang(Config.s_NickServ, u, ACCESS_DENIED); + return MOD_CONT; + } + else if (nc->display == params[1] || (Config.StrictPasswords && len < 5)) + { + notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD); + return MOD_CONT; + } + else if (len > Config.PassLen) + { + notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG); + return MOD_CONT; + } + + std::string buf = params[1].c_str(); + if (enc_encrypt(buf, nc->pass)) + { + Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (saset)"; + notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_FAILED, nc->display); + return MOD_CONT; + } + + std::string tmp_pass; + if (enc_decrypt(nc->pass, tmp_pass) == 1) + notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED_TO, nc->display, tmp_pass.c_str()); + else + notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED, nc->display); + + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET PASSWORD on " << nc->display << " (e-mail: "<< (nc->email ? nc->email : "none") << ")"; + + if (Config.WallSetpass) + ircdproto->SendGlobops(NickServ, "\2%s\2 used SASET PASSWORD on \2%s\2", u->nick.c_str(), nc->display); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PASSWORD); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_PASSWORD); + } +}; + +class NSSASet : public Module +{ +public: + NSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + Command *c = new CommandNSSASet("SASET"); + this->AddCommand(NickServ, c); + c->AddSubcommand(new CommandNSSASetDisplay("DISPLAY")); + c->AddSubcommand(new CommandNSSASetPassword("PASSWORD")); + } +}; + +MODULE_INIT(NSSASet) diff --git a/src/core/ns_saset_noexpire.cpp b/src/core/ns_saset_noexpire.cpp new file mode 100644 index 000000000..a5df0bb19 --- /dev/null +++ b/src/core/ns_saset_noexpire.cpp @@ -0,0 +1,87 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSASetNoexpire : public Command +{ + public: + CommandNSSASetNoexpire(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/noexpire") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickAlias *na = findnick(params[0]); + assert(na); + + ci::string param = params.size() > 1 ? params[1] : ""; + + if (param == "ON") + { + na->SetFlag(NS_NO_EXPIRE); + notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_ON, na->nick); + } + else if (param == "OFF") + { + na->UnsetFlag(NS_NO_EXPIRE); + notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_OFF, na->nick); + } + else + this->OnSyntaxError(u, "NOEXPIRE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_NOEXPIRE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_NOEXPIRE); + } +}; + +class NSSASetNoexpire : public Module +{ + public: + NSSASetNoexpire(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetNoexpire("NOEXPIRE")); + } + + ~NSSASetNoexpire() + { + Command *c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("NOEXPRE"); + } +}; + +MODULE_INIT(NSSASetNoexpire) diff --git a/src/core/ns_sendpass.c b/src/core/ns_sendpass.cpp index 0ce8f6c5c..6d4358f06 100644 --- a/src/core/ns_sendpass.c +++ b/src/core/ns_sendpass.cpp @@ -14,6 +14,8 @@ #include "module.h" +static bool SendPassMail(User *u, NickAlias *na, const std::string &pass); + class CommandNSSendPass : public Command { public: @@ -34,34 +36,14 @@ class CommandNSSendPass : public Command notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); else { - char buf[BUFSIZE]; std::string tmp_pass; if (enc_decrypt(na->nc->pass,tmp_pass) == 1) { - MailInfo *mail; - - snprintf(buf, sizeof(buf), getstring(na, NICK_SENDPASS_SUBJECT), na->nick); - mail = MailBegin(u, na->nc, buf, Config.s_NickServ); - if (!mail) - return MOD_CONT; - - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_HEAD)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_1), na->nick); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_2), tmp_pass.c_str()); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_4)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_5), Config.NetworkName); - fprintf(mail->pipe, "\n.\n"); - - MailEnd(mail); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick; - notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick); + if (SendPassMail(u, na, tmp_pass)) + { + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick; + notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick); + } } else notice_lang(Config.s_NickServ, u, NICK_SENDPASS_UNAVAILABLE); @@ -80,6 +62,11 @@ class CommandNSSendPass : public Command { syntax_error(Config.s_NickServ, u, "SENDPASS", NICK_SENDPASS_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SENDPASS); + } }; class NSSendPass : public Module @@ -91,7 +78,7 @@ class NSSendPass : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSSendPass()); + this->AddCommand(NickServ, new CommandNSSendPass()); if (!Config.UseMail) throw ModuleException("Not using mail, whut."); @@ -99,13 +86,17 @@ class NSSendPass : public Module std::string tmp_pass = "plain:tmp"; if (enc_decrypt(tmp_pass, tmp_pass) == -1) throw ModuleException("Incompatible with the encryption module being used"); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SENDPASS); } }; +static bool SendPassMail(User *u, NickAlias *na, const std::string &pass) +{ + char subject[BUFSIZE], message[BUFSIZE]; + + snprintf(subject, sizeof(subject), getstring(na, NICK_SENDPASS_SUBJECT), na->nick); + snprintf(message, sizeof(message), getstring(na, NICK_SENDPASS), na->nick, pass.c_str(), Config.NetworkName); + + return Mail(u, na->nc, Config.s_NickServ, subject, message); +} + MODULE_INIT(NSSendPass) diff --git a/src/core/ns_set.c b/src/core/ns_set.c deleted file mode 100644 index 1cd797881..000000000 --- a/src/core/ns_set.c +++ /dev/null @@ -1,557 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -class CommandNSSet : public Command -{ - private: - CommandReturn DoSetDisplay(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "DISPLAY"); - return MOD_CONT; - } - - int i; - NickAlias *na; - - /* First check whether param is a valid nick of the group */ - for (i = 0; i < nc->aliases.count; ++i) - { - na = static_cast<NickAlias *>(nc->aliases.list[i]); - if (na->nick == param) - { - param = na->nick; /* Because case may differ */ - break; - } - } - - if (i == nc->aliases.count) - { - notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_INVALID); - return MOD_CONT; - } - - change_core_display(nc, param.c_str()); - notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_CHANGED, nc->display); - return MOD_CONT; - } - - CommandReturn DoSetPassword(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - std::string buf, tmp_pass; - - if (param.empty()) - { - this->OnSyntaxError(u, "PASSWORD"); - return MOD_CONT; - } - - int len = param.size(); - - if (nc->display == param || (Config.StrictPasswords && len < 5)) - { - notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD); - return MOD_CONT; - } - else if (len > Config.PassLen) - { - notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG); - return MOD_CONT; - } - - buf = param.c_str(); /* conversion from ci::string to std::string */ - if (enc_encrypt(buf, nc->pass) < 0) - { - Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (set)"; - notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_FAILED); - return MOD_CONT; - } - - if (enc_decrypt(nc->pass, tmp_pass) == 1) - notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED_TO, tmp_pass.c_str()); - else - notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (nc->email ? nc->email : "none") << ") changed its password."; - - return MOD_CONT; - } - - CommandReturn DoSetLanguage(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 1 ? params[1].c_str() : NULL; - - if (!param) - { - this->OnSyntaxError(u, "LANGUAGE"); - return MOD_CONT; - } - - int langnum; - - if (param[strspn(param, "0123456789")]) /* i.e. not a number */ - { - syntax_error(Config.s_NickServ, u, "SET LANGUAGE", NICK_SET_LANGUAGE_SYNTAX); - return MOD_CONT; - } - langnum = atoi(param) - 1; - if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0) - { - notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ); - return MOD_CONT; - } - nc->language = langlist[langnum]; - notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_CHANGED); - return MOD_CONT; - } - - CommandReturn DoSetUrl(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 1 ? params[1].c_str() : NULL; - - if (nc->url) - delete [] nc->url; - - if (param) - { - nc->url = sstrdup(param); - notice_lang(Config.s_NickServ, u, NICK_SET_URL_CHANGED, param); - } - else - { - nc->url = NULL; - notice_lang(Config.s_NickServ, u, NICK_SET_URL_UNSET); - } - return MOD_CONT; - } - - CommandReturn DoSetEmail(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 1 ? params[1].c_str() : NULL; - - if (!param && Config.NSForceEmail) - { - notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET_IMPOSSIBLE); - return MOD_CONT; - } - else if (param && !MailValidate(param)) - { - notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param); - return MOD_CONT; - } - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (nc->email ? nc->email : "none") << ") changed its e-mail to " << (param ? param : "none"); - - if (nc->email) - delete [] nc->email; - - if (param) - { - nc->email = sstrdup(param); - notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_CHANGED, param); - } - else - { - nc->email = NULL; - notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET); - } - return MOD_CONT; - } - - CommandReturn DoSetICQ(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 1 ? params[1].c_str() : NULL; - - if (param) - { - int32 tmp = atol(param); - if (!tmp) - notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_INVALID, param); - else - { - nc->icq = tmp; - notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_CHANGED, param); - } - } - else - { - nc->icq = 0; - notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_UNSET); - } - return MOD_CONT; - } - - CommandReturn DoSetGreet(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - const char *param = params.size() > 1 ? params[1].c_str() : NULL; - - if (nc->greet) - delete [] nc->greet; - - if (param) - { - char buf[BUFSIZE]; - const char *rest = params.size() > 2 ? params[2].c_str() : NULL; - - snprintf(buf, sizeof(buf), "%s%s%s", param, rest ? " " : "", rest ? rest : ""); - - nc->greet = sstrdup(buf); - notice_lang(Config.s_NickServ, u, NICK_SET_GREET_CHANGED, buf); - } - else - { - nc->greet = NULL; - notice_lang(Config.s_NickServ, u, NICK_SET_GREET_UNSET); - } - return MOD_CONT; - } - - CommandReturn DoSetKill(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "KILL"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SET_KILL_ON); - } - else if (param == "QUICK") - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SET_KILL_QUICK); - } - else if (param == "IMMED") - { - if (Config.NSAllowKillImmed) - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_IMMED); - nc->UnsetFlag(NI_KILL_QUICK); - notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED); - } - else - notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED_DISABLED); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - notice_lang(Config.s_NickServ, u, NICK_SET_KILL_OFF); - } - else - syntax_error(Config.s_NickServ, u, "SET KILL", Config.NSAllowKillImmed ? NICK_SET_KILL_IMMED_SYNTAX : NICK_SET_KILL_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetSecure(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "SECURE"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_SECURE); - notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_ON); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_SECURE); - notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_OFF); - } - else - syntax_error(Config.s_NickServ, u, "SET SECURE", NICK_SET_SECURE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetPrivate(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "PRIVATE"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_PRIVATE); - notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_ON); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_PRIVATE); - notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_OFF); - } - else - syntax_error(Config.s_NickServ, u, "SET PRIVATE", NICK_SET_PRIVATE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetMsg(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "MSG"); - return MOD_CONT; - } - - if (!Config.UsePrivmsg) - { - notice_lang(Config.s_NickServ, u, NICK_SET_OPTION_DISABLED, "MSG"); - return MOD_CONT; - } - - if (param == "ON") - { - nc->SetFlag(NI_MSG); - notice_lang(Config.s_NickServ, u, NICK_SET_MSG_ON); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_MSG); - notice_lang(Config.s_NickServ, u, NICK_SET_MSG_OFF); - } - else - syntax_error(Config.s_NickServ, u, "SET MSG", NICK_SET_MSG_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetHide(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "HIDE"); - return MOD_CONT; - } - - int onmsg, offmsg; - NickCoreFlag flag; - - if (param == "EMAIL") - { - flag = NI_HIDE_EMAIL; - onmsg = NICK_SET_HIDE_EMAIL_ON; - offmsg = NICK_SET_HIDE_EMAIL_OFF; - } - else if (param == "USERMASK") - { - flag = NI_HIDE_MASK; - onmsg = NICK_SET_HIDE_MASK_ON; - offmsg = NICK_SET_HIDE_MASK_OFF; - } - else if (param == "STATUS") - { - flag = NI_HIDE_STATUS; - onmsg = NICK_SET_HIDE_STATUS_ON; - offmsg = NICK_SET_HIDE_STATUS_OFF; - } - else if (param == "QUIT") - { - flag = NI_HIDE_QUIT; - onmsg = NICK_SET_HIDE_QUIT_ON; - offmsg = NICK_SET_HIDE_QUIT_OFF; - } - else - { - syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX); - return MOD_CONT; - } - - param = params.size() > 2 ? params[2] : ""; - if (param.empty()) - syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX); - else if (param == "ON") - { - nc->SetFlag(flag); - notice_lang(Config.s_NickServ, u, onmsg, Config.s_NickServ); - } - else if (param == "OFF") - { - nc->UnsetFlag(flag); - notice_lang(Config.s_NickServ, u, offmsg, Config.s_NickServ); - } - else - syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX); - return MOD_CONT; - } - - CommandReturn DoSetAutoOP(User *u, const std::vector<ci::string> ¶ms, NickCore *nc) - { - ci::string param = params.size() > 1 ? params[1] : ""; - - if (param.empty()) - { - this->OnSyntaxError(u, "AUTOOP"); - return MOD_CONT; - } - - /** - * This works the other way around, the absence of this flag denotes ON - * This is so when people upgrade, and dont have the flag - * the default is on - **/ - if (param == "ON") - { - nc->SetFlag(NI_AUTOOP); - notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_ON); - } - else if (param == "OFF") - { - nc->UnsetFlag(NI_AUTOOP); - notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_OFF); - } - else - syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SET_AUTOOP_SYNTAX); - - return MOD_CONT; - } - public: - CommandNSSet() : Command("SET", 1, 3) - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - ci::string cmd = params[0]; - - if (readonly) - { - notice_lang(Config.s_NickServ, u, NICK_SET_DISABLED); - return MOD_CONT; - } - -/* - if (na->HasFlag(NS_FORBIDDEN)) - notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); -*/ - if (u->Account()->HasFlag(NI_SUSPENDED)) - notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, u->Account()->display); - else if (cmd == "DISPLAY") - return this->DoSetDisplay(u, params, u->Account()); - else if (cmd == "PASSWORD") - return this->DoSetPassword(u, params, u->Account()); - else if (cmd == "LANGUAGE") - return this->DoSetLanguage(u, params, u->Account()); - else if (cmd == "URL") - return this->DoSetUrl(u, params, u->Account()); - else if (cmd == "EMAIL") - return this->DoSetEmail(u, params, u->Account()); - else if (cmd == "ICQ") - return this->DoSetICQ(u, params, u->Account()); - else if (cmd == "GREET") - return this->DoSetGreet(u, params, u->Account()); - else if (cmd == "KILL") - return this->DoSetKill(u, params, u->Account()); - else if (cmd == "SECURE") - return this->DoSetSecure(u, params, u->Account()); - else if (cmd == "PRIVATE") - return this->DoSetPrivate(u, params, u->Account()); - else if (cmd == "MSG") - return this->DoSetMsg(u, params, u->Account()); - else if (cmd == "HIDE") - return this->DoSetHide(u, params, u->Account()); - else if (cmd == "AUTOOP") - return this->DoSetAutoOP(u, params, u->Account()); - else - notice_lang(Config.s_NickServ, u, NICK_SET_UNKNOWN_OPTION, cmd.c_str()); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - if (subcommand.empty()) - notice_help(Config.s_NickServ, u, NICK_HELP_SET); - else if (subcommand == "DISPLAY") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_DISPLAY); - else if (subcommand == "PASSWORD") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_PASSWORD); - else if (subcommand == "URL") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_URL); - else if (subcommand == "EMAIL") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_EMAIL); - else if (subcommand == "ICQ") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_ICQ); - else if (subcommand == "GREET") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_GREET); - else if (subcommand == "KILL") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_KILL); - else if (subcommand == "SECURE") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_SECURE); - else if (subcommand == "PRIVATE") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_PRIVATE); - else if (subcommand == "MSG") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_MSG); - else if (subcommand == "HIDE") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_HIDE); - else if (subcommand == "AUTOOP") - notice_help(Config.s_NickServ, u, NICK_HELP_SET_AUTOOP); - else - return false; - - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX); - } -}; - -class NSSet : public Module -{ - public: - NSSet(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(NICKSERV, new CommandNSSet()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET); - } -}; - -MODULE_INIT(NSSet) diff --git a/src/core/ns_set.cpp b/src/core/ns_set.cpp new file mode 100644 index 000000000..ecb1355c3 --- /dev/null +++ b/src/core/ns_set.cpp @@ -0,0 +1,239 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSet : public Command +{ + std::map<ci::string, Command *> subcommands; + public: + CommandNSSet(const ci::string &cname) : Command(cname, 1, 3) + { + } + + ~CommandNSSet() + { + for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + { + delete it->second; + } + this->subcommands.clear(); + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (readonly) + { + notice_lang(Config.s_NickServ, u, NICK_SET_DISABLED); + return MOD_CONT; + } + + if (u->Account()->HasFlag(NI_SUSPENDED)) + { + notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, u->Account()->display); + return MOD_CONT; + } + + Command *c = this->FindCommand(params[0]); + + if (c) + { + ci::string cmdparams; + for (std::vector<ci::string>::const_iterator it = params.begin() + 1; it != params.end(); ++it) + cmdparams += " " + *it; + if (!cmdparams.empty()) + cmdparams.erase(cmdparams.begin()); + mod_run_cmd(NickServ, u, c, params[0], cmdparams); + } + else + { + notice_lang(Config.s_NickServ, u, NICK_SET_UNKNOWN_OPTION, params[0].c_str()); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + if (subcommand.empty()) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_HEAD); + for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it) + it->second->OnServHelp(u); + notice_help(Config.s_NickServ, u, NICK_HELP_SET_TAIL); + return true; + } + else + { + Command *c = this->FindCommand(subcommand); + + if (c) + { + return c->OnHelp(u, subcommand); + } + } + + return false; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET); + } + + bool AddSubcommand(Command *c) + { + return this->subcommands.insert(std::make_pair(c->name, c)).second; + } + + bool DelSubcommand(const ci::string &command) + { + return this->subcommands.erase(command); + } + + Command *FindCommand(const ci::string &subcommand) + { + std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand); + + if (it != this->subcommands.end()) + { + return it->second; + } + + return NULL; + } +}; + +class CommandNSSetDisplay : public Command +{ + public: + CommandNSSetDisplay(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickAlias *na = findnick(params[0]); + + if (!na || na->nc != u->Account()) + { + notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_INVALID); + return MOD_CONT; + } + + change_core_display(u->Account(), params[0].c_str()); + notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_CHANGED, u->Account()->display); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_DISPLAY); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_DISPLAY); + } +}; + +class CommandNSSetPassword : public Command +{ + public: + CommandNSSetPassword(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ci::string param = params[0]; + + int len = param.size(); + + if (u->Account()->display == param || (Config.StrictPasswords && len < 5)) + { + notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD); + return MOD_CONT; + } + else if (len > Config.PassLen) + { + notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG); + return MOD_CONT; + } + + std::string buf = param.c_str(); /* conversion from ci::string to std::string */ + if (enc_encrypt(buf, u->Account()->pass) < 0) + { + Alog() << Config.s_NickServ << ": Failed to encrypt password for " << u->Account()->display << " (set)"; + notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_FAILED); + return MOD_CONT; + } + + std::string tmp_pass; + if (enc_decrypt(u->Account()->pass, tmp_pass) == 1) + notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED_TO, tmp_pass.c_str()); + else + notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED); + + Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (u->Account()->email ? u->Account()->email : "none") << ") changed its password."; + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_PASSWORD); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + // XXX + syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_PASSWORD); + } +}; + +class NSSet : public Module +{ + public: + NSSet(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + Command *set = new CommandNSSet("SET"); + this->AddCommand(NickServ, set); + set->AddSubcommand(new CommandNSSetDisplay("DISPLAY")); + set->AddSubcommand(new CommandNSSetPassword("PASSWORD")); + } +}; + +MODULE_INIT(NSSet) diff --git a/src/core/ns_set_autoop.cpp b/src/core/ns_set_autoop.cpp new file mode 100644 index 000000000..d1c0d0d81 --- /dev/null +++ b/src/core/ns_set_autoop.cpp @@ -0,0 +1,131 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetAutoOp : public Command +{ + public: + CommandNSSetAutoOp(const ci::string &cname) : Command(cname, 2) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (params[0] == "ON") + { + u->Account()->SetFlag(NI_AUTOOP); + notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_ON); + } + else if (params[0] == "OFF") + { + u->Account()->UnsetFlag(NI_AUTOOP); + notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_OFF); + } + else + this->OnSyntaxError(u, "AUTOOP"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_AUTOOP); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SET_AUTOOP_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_AUTOOP); + } +}; + +class CommandNSSASetAutoOp : public Command +{ + public: + CommandNSSASetAutoOp(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/autoop") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + if (param == "ON") + { + nc->SetFlag(NI_AUTOOP); + notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_ON, nc->display); + } + else if (param == "OFF") + { + nc->UnsetFlag(NI_AUTOOP); + notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_OFF, nc->display); + } + else + this->OnSyntaxError(u, "AUTOOP"); + + return MOD_CONT; + } + + bool Help(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_AUTOOP); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SASET_AUTOOP_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_AUTOOP); + } +}; + +class NSSetAutoOp : public Module +{ + public: + NSSetAutoOp(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *set = FindCommand(NickServ, "SET"); + + if (set) + set->AddSubcommand(new CommandNSSetAutoOp("AUTOOP")); + } + + ~NSSetAutoOp() + { + Command *set = FindCommand(NickServ, "SET"); + + if (set) + set->DelSubcommand("AUTOOP"); + } +}; + +MODULE_INIT(NSSetAutoOp) diff --git a/src/core/ns_set_email.cpp b/src/core/ns_set_email.cpp new file mode 100644 index 000000000..ec1b78c83 --- /dev/null +++ b/src/core/ns_set_email.cpp @@ -0,0 +1,160 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetEmail : public Command +{ + public: + CommandNSSetEmail(const ci::string &cname) : Command(cname, 0) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (params.empty() && Config.NSForceEmail) + { + notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET_IMPOSSIBLE); + return MOD_CONT; + } + else if (!params.empty() && !MailValidate(params[0].c_str())) + { + notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, params[0].c_str()); + return MOD_CONT; + } + + Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (u->Account()->email ? u->Account()->email : "none") << ") changed its e-mail to " << (!params.empty() ? params[0] : "none"); + + if (u->Account()->email) + delete [] u->Account()->email; + + if (!params.empty()) + { + u->Account()->email = sstrdup(params[0].c_str()); + notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_CHANGED, params[0].c_str()); + } + else + { + u->Account()->email = NULL; + notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_EMAIL); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_EMAIL); + } +}; + +class CommandNSSASetEmail : public Command +{ + public: + CommandNSSASetEmail(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/email") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + const char *param = params.size() > 1 ? params[1].c_str() : NULL; + + if (!param && Config.NSForceEmail) + { + notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET_IMPOSSIBLE); + return MOD_CONT; + } + else if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper()) + { + notice_lang(Config.s_NickServ, u, ACCESS_DENIED); + return MOD_CONT; + } + else if (param && !MailValidate(param)) + { + notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param); + return MOD_CONT; + } + + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET EMAIL on " << nc->display << " (e-mail: " << (nc->email ? nc->email : "none") << ")"; + + if (nc->email) + delete [] nc->email; + + if (param) + { + nc->email = sstrdup(param); + notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_CHANGED, nc->display, param); + } + else + { + nc->email = NULL; + notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET, nc->display); + } + + return MOD_CONT; + } + + bool OnHelp(User *u) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_EMAIL); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_EMAIL); + } +}; + +class NSSetEmail : public Module +{ + public: + NSSetEmail(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetEmail("EMAIL")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetEmail("EMAIL")); + } + + ~NSSetEmail() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("EMAIL"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("EMAIL"); + } +}; + +MODULE_INIT(NSSetEmail) diff --git a/src/core/ns_set_greet.cpp b/src/core/ns_set_greet.cpp new file mode 100644 index 000000000..0a1e94547 --- /dev/null +++ b/src/core/ns_set_greet.cpp @@ -0,0 +1,129 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetGreet : public Command +{ + public: + CommandNSSetGreet(const ci::string &cname) : Command(cname, 0) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (u->Account()->greet) + delete [] u->Account()->greet; + + if (!params.empty()) + { + u->Account()->greet = sstrdup(params[0].c_str()); + notice_lang(Config.s_NickServ, u, NICK_SET_GREET_CHANGED, u->Account()->greet); + } + else + { + u->Account()->greet = NULL; + notice_lang(Config.s_NickServ, u, NICK_SET_GREET_UNSET); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_GREET); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_GREET); + } +}; + +class CommandNSSASetGreet : public Command +{ + public: + CommandNSSASetGreet(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/greet") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + const char *param = params.size() > 1 ? params[1].c_str() : NULL; + + if (nc->greet) + delete [] nc->greet; + + if (param) + { + nc->greet = sstrdup(param); + notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_CHANGED, nc->display, nc->greet); + } + else + { + nc->greet = NULL; + notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_UNSET, nc->display); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_GREET); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_GREET); + } +}; + +class NSSetGreet : public Module +{ + public: + NSSetGreet(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetGreet("GREET")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetGreet("GREET")); + } + + ~NSSetGreet() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("GREET"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("GREET"); + } +}; + +MODULE_INIT(NSSetGreet) diff --git a/src/core/ns_set_hide.cpp b/src/core/ns_set_hide.cpp new file mode 100644 index 000000000..e17fac21f --- /dev/null +++ b/src/core/ns_set_hide.cpp @@ -0,0 +1,200 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetHide : public Command +{ + public: + CommandNSSetHide(const ci::string &cname) : Command(cname, 2) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + int onmsg, offmsg; + NickCoreFlag flag; + + if (params[0] == "EMAIL") + { + flag = NI_HIDE_EMAIL; + onmsg = NICK_SET_HIDE_EMAIL_ON; + offmsg = NICK_SET_HIDE_EMAIL_OFF; + } + else if (params[0] == "USERMASK") + { + flag = NI_HIDE_MASK; + onmsg = NICK_SET_HIDE_MASK_ON; + offmsg = NICK_SET_HIDE_MASK_OFF; + } + else if (params[0] == "STATUS") + { + flag = NI_HIDE_STATUS; + onmsg = NICK_SET_HIDE_STATUS_ON; + offmsg = NICK_SET_HIDE_STATUS_OFF; + } + else if (params[0] == "QUIT") + { + flag = NI_HIDE_QUIT; + onmsg = NICK_SET_HIDE_QUIT_ON; + offmsg = NICK_SET_HIDE_QUIT_OFF; + } + else + { + this->OnSyntaxError(u, "HIDE"); + return MOD_CONT; + } + + if (params[1] == "ON") + { + u->Account()->SetFlag(flag); + notice_lang(Config.s_NickServ, u, onmsg, Config.s_NickServ); + } + else if (params[1] == "OFF") + { + u->Account()->UnsetFlag(flag); + notice_lang(Config.s_NickServ, u, offmsg, Config.s_NickServ); + } + else + this->OnSyntaxError(u, "HIDE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_HIDE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_HIDE); + } +}; + +class CommandNSSASetHide : public Command +{ + public: + CommandNSSASetHide(const ci::string &cname) : Command(cname, 3, 3, "nickserv/saset/command") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + int onmsg, offmsg; + NickCoreFlag flag; + + if (param == "EMAIL") + { + flag = NI_HIDE_EMAIL; + onmsg = NICK_SASET_HIDE_EMAIL_ON; + offmsg = NICK_SASET_HIDE_EMAIL_OFF; + } + else if (param == "USERMASK") + { + flag = NI_HIDE_MASK; + onmsg = NICK_SASET_HIDE_MASK_ON; + offmsg = NICK_SASET_HIDE_MASK_OFF; + } + else if (param == "STATUS") + { + flag = NI_HIDE_STATUS; + onmsg = NICK_SASET_HIDE_STATUS_ON; + offmsg = NICK_SASET_HIDE_STATUS_OFF; + } + else if (param == "QUIT") + { + flag = NI_HIDE_QUIT; + onmsg = NICK_SASET_HIDE_QUIT_ON; + offmsg = NICK_SASET_HIDE_QUIT_OFF; + } + else + { + this->OnSyntaxError(u, "HIDE"); + return MOD_CONT; + } + + param = params[2]; + if (param.empty()) + this->OnSyntaxError(u, "HIDE"); + else if (param == "ON") + { + nc->SetFlag(flag); + notice_lang(Config.s_NickServ, u, onmsg, nc->display, Config.s_NickServ); + } + else if (param == "OFF") + { + nc->UnsetFlag(flag); + notice_lang(Config.s_NickServ, u, offmsg, nc->display, Config.s_NickServ); + } + else + this->OnSyntaxError(u, "HIDE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HIDE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_HIDE); + } +}; + +class NSSetHide : public Module +{ + public: + NSSetHide(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *set = FindCommand(NickServ, "SET"); + + if (set) + set->AddSubcommand(new CommandNSSetHide("HIDE")); + } + + ~NSSetHide() + { + Command *set = FindCommand(NickServ, "SET"); + + if (set) + set->DelSubcommand("HIDE"); + } +}; + +MODULE_INIT(NSSetHide) diff --git a/src/core/ns_set_icq.cpp b/src/core/ns_set_icq.cpp new file mode 100644 index 000000000..a00810bac --- /dev/null +++ b/src/core/ns_set_icq.cpp @@ -0,0 +1,136 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetICQ : public Command +{ + public: + CommandNSSetICQ(const ci::string &cname) : Command(cname, 0) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (!params.empty()) + { + int32 tmp = atol(params[0].c_str()); + if (!tmp) + notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_INVALID, params[0].c_str()); + else + { + u->Account()->icq = tmp; + notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_CHANGED, params[0].c_str()); + } + } + else + { + u->Account()->icq = 0; + notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_UNSET); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_ICQ); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_ICQ); + } +}; + +class CommandNSSASetICQ : public Command +{ + public: + CommandNSSASetICQ(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/icq") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + const char *param = params.size() > 1 ? params[1].c_str() : NULL; + + if (param) + { + int32 tmp = atol(param); + + if (tmp) + notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_INVALID, param); + else + { + nc->icq = tmp; + notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_CHANGED, nc->display, param); + } + } + else + { + nc->icq = 0; + notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_UNSET, nc->display); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_ICQ); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_ICQ); + } +}; + +class NSSetICQ : public Module +{ + public: + NSSetICQ(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetICQ("ICQ")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetICQ("ICQ")); + } + + ~NSSetICQ() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("ICQ"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("ICQ"); + } +}; + +MODULE_INIT(NSSetICQ) diff --git a/src/core/ns_set_kill.cpp b/src/core/ns_set_kill.cpp new file mode 100644 index 000000000..d9d6caa7c --- /dev/null +++ b/src/core/ns_set_kill.cpp @@ -0,0 +1,183 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetKill : public Command +{ + public: + CommandNSSetKill(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (params[0] == "ON") + { + u->Account()->SetFlag(NI_KILLPROTECT); + u->Account()->UnsetFlag(NI_KILL_QUICK); + u->Account()->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SET_KILL_ON); + } + else if (params[0] == "QUICK") + { + u->Account()->SetFlag(NI_KILLPROTECT); + u->Account()->SetFlag(NI_KILL_QUICK); + u->Account()->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SET_KILL_QUICK); + } + else if (params[0] == "IMMED") + { + if (Config.NSAllowKillImmed) + { + u->Account()->SetFlag(NI_KILLPROTECT); + u->Account()->SetFlag(NI_KILL_IMMED); + u->Account()->UnsetFlag(NI_KILL_QUICK); + notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED); + } + else + notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED_DISABLED); + } + else if (params[0] == "OFF") + { + u->Account()->UnsetFlag(NI_KILLPROTECT); + u->Account()->UnsetFlag(NI_KILL_QUICK); + u->Account()->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SET_KILL_OFF); + } + else + this->OnSyntaxError(u, "KILL"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_KILL); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET KILL", Config.NSAllowKillImmed ? NICK_SET_KILL_IMMED_SYNTAX : NICK_SET_KILL_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_KILL); + } +}; + +class CommandNSSASetKill : public Command +{ + public: + CommandNSSASetKill(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/kill") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + if (param == "ON") + { + nc->SetFlag(NI_KILLPROTECT); + nc->UnsetFlag(NI_KILL_QUICK); + nc->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_ON, nc->display); + } + else if (param == "QUICK") + { + nc->SetFlag(NI_KILLPROTECT); + nc->SetFlag(NI_KILL_QUICK); + nc->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_QUICK, nc->display); + } + else if (param == "IMMED") + { + if (Config.NSAllowKillImmed) + { + nc->SetFlag(NI_KILLPROTECT); + nc->SetFlag(NI_KILL_IMMED); + nc->UnsetFlag(NI_KILL_QUICK); + notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED, nc->display); + } + else + notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED_DISABLED); + } + else if (param == "OFF") + { + nc->UnsetFlag(NI_KILLPROTECT); + nc->UnsetFlag(NI_KILL_QUICK); + nc->UnsetFlag(NI_KILL_IMMED); + notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_OFF, nc->display); + } + else + this->OnSyntaxError(u, "KILL"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_KILL); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET KILL", Config.NSAllowKillImmed ? NICK_SASET_KILL_IMMED_SYNTAX : NICK_SASET_KILL_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_KILL); + } +}; + +class NSSetKill : public Module +{ + public: + NSSetKill(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetKill("KILL")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetKill("KILL")); + } + + ~NSSetKill() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("KILL"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("KILL"); + } +}; + +MODULE_INIT(NSSetKill) diff --git a/src/core/ns_set_language.cpp b/src/core/ns_set_language.cpp new file mode 100644 index 000000000..a175f91a7 --- /dev/null +++ b/src/core/ns_set_language.cpp @@ -0,0 +1,143 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetLanguage : public Command +{ + public: + CommandNSSetLanguage(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + const char *param = params[0].c_str(); + + if (param[strspn(param, "0123456789")]) /* i.e. not a number */ + { + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + int langnum = atoi(param) - 1; + if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0) + { + notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ); + return MOD_CONT; + } + + u->Account()->language = langlist[langnum]; + notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_CHANGED); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_LANGUAGE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET LANGUAGE", NICK_SET_LANGUAGE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_LANGUAGE); + } +}; + +class CommandNSSASetLanguage : public Command +{ + public: + CommandNSSASetLanguage(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/language") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + const char *param = params[1].c_str(); + + if (param[strspn(param, "0123456789")]) /* i.e. not a number */ + { + this->OnSyntaxError(u, "LANGUAGE"); + return MOD_CONT; + } + int langnum = atoi(param) - 1; + if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0) + { + notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ); + return MOD_CONT; + } + nc->language = langlist[langnum]; + notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_CHANGED); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_LANGUAGE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET LANGUAGE", NICK_SASET_LANGUAGE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_LANGUAGE); + } +}; + +class NSSetLanguage : public Module +{ + public: + NSSetLanguage(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetLanguage("LANGUAGE")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetLanguage("LANGUAGE")); + } + + ~NSSetLanguage() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("LANGUAGE"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("LANGUAGE"); + } +}; + +MODULE_INIT(NSSetLanguage) diff --git a/src/core/ns_set_message.cpp b/src/core/ns_set_message.cpp new file mode 100644 index 000000000..89f3cca0a --- /dev/null +++ b/src/core/ns_set_message.cpp @@ -0,0 +1,149 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetMessage : public Command +{ + public: + CommandNSSetMessage(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (!Config.UsePrivmsg) + { + notice_lang(Config.s_NickServ, u, NICK_SET_OPTION_DISABLED, "MSG"); + return MOD_CONT; + } + + if (params[0] == "ON") + { + u->Account()->SetFlag(NI_MSG); + notice_lang(Config.s_NickServ, u, NICK_SET_MSG_ON); + } + else if (params[0] == "OFF") + { + u->Account()->UnsetFlag(NI_MSG); + notice_lang(Config.s_NickServ, u, NICK_SET_MSG_OFF); + } + else + this->OnSyntaxError(u, "MSG"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_MSG); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET MSG", NICK_SET_MSG_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_MSG); + } +}; + +class CommandNSSASetMessage : public Command +{ + public: + CommandNSSASetMessage(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/message") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + if (!Config.UsePrivmsg) + { + notice_lang(Config.s_NickServ, u, NICK_SASET_OPTION_DISABLED, "MSG"); + return MOD_CONT; + } + + if (param == "ON") + { + nc->SetFlag(NI_MSG); + notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_ON, nc->display); + } + else if (param == "OFF") + { + nc->UnsetFlag(NI_MSG); + notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_OFF, nc->display); + } + else + this->OnSyntaxError(u, "MSG"); + + return MOD_CONT; + } + + bool OnHelp(User *u) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_MSG); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET MSG", NICK_SASET_MSG_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_MSG); + } +}; + +class NSSetMessage : public Module +{ + public: + NSSetMessage(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetMessage("MSG")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetMessage("MSG")); + } + + ~NSSetMessage() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("MSG"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("MSG"); + } +}; + +MODULE_INIT(NSSetMessage) diff --git a/src/core/ns_set_private.cpp b/src/core/ns_set_private.cpp new file mode 100644 index 000000000..661287929 --- /dev/null +++ b/src/core/ns_set_private.cpp @@ -0,0 +1,137 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetPrivate : public Command +{ + public: + CommandNSSetPrivate(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (params[0] == "ON") + { + u->Account()->SetFlag(NI_PRIVATE); + notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_ON); + } + else if (params[0] == "OFF") + { + u->Account()->UnsetFlag(NI_PRIVATE); + notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_OFF); + } + else + this->OnSyntaxError(u, "PRIVATE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_PRIVATE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET PRIVATE", NICK_SET_PRIVATE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_help(Config.s_NickServ, u, NICK_HELP_CMD_SET_PRIVATE); + } +}; + +class CommandNSSASetPrivate : public Command +{ + public: + CommandNSSASetPrivate(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/private") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + if (param == "ON") + { + nc->SetFlag(NI_PRIVATE); + notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_ON, nc->display); + } + else if (param == "OFF") + { + nc->UnsetFlag(NI_PRIVATE); + notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_OFF, nc->display); + } + else + this->OnSyntaxError(u, "PRIVATE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PRIVATE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET PRIVATE", NICK_SASET_PRIVATE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_help(Config.s_NickServ, u, NICK_HELP_CMD_SASET_PRIVATE); + } +}; + +class NSSetPrivate : public Module +{ + public: + NSSetPrivate(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetPrivate("PRIVATE")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetPrivate("PRIVATE")); + } + + ~NSSetPrivate() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("PRIVATE"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("PRIVATE"); + } +}; + +MODULE_INIT(NSSetPrivate) diff --git a/src/core/ns_set_secure.cpp b/src/core/ns_set_secure.cpp new file mode 100644 index 000000000..a452a31f3 --- /dev/null +++ b/src/core/ns_set_secure.cpp @@ -0,0 +1,137 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetSecure : public Command +{ + public: + CommandNSSetSecure(const ci::string &cname) : Command(cname, 1) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (params[0] == "ON") + { + u->Account()->SetFlag(NI_SECURE); + notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_ON); + } + else if (params[0] == "OFF") + { + u->Account()->UnsetFlag(NI_SECURE); + notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_OFF); + } + else + this->OnSyntaxError(u, "SECURE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_SECURE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SET SECURE", NICK_SET_SECURE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_SECURE); + } +}; + +class CommandNSSASetSecure : public Command +{ + public: + CommandNSSASetSecure(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/secure") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + ci::string param = params[1]; + + if (param == "ON") + { + nc->SetFlag(NI_SECURE); + notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_ON, nc->display); + } + else if (param == "OFF") + { + nc->UnsetFlag(NI_SECURE); + notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_OFF, nc->display); + } + else + this->OnSyntaxError(u, "SECURE"); + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_SECURE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &) + { + syntax_error(Config.s_NickServ, u, "SASET SECURE", NICK_SASET_SECURE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_SECURE); + } +}; + +class NSSetSecure : public Module +{ + public: + NSSetSecure(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetSecure("SECURE")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetSecure("SECURE")); + } + + ~NSSetSecure() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("SECURE"); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("SECURE"); + } +}; + +MODULE_INIT(NSSetSecure) diff --git a/src/core/ns_set_url.cpp b/src/core/ns_set_url.cpp new file mode 100644 index 000000000..5ef83d32e --- /dev/null +++ b/src/core/ns_set_url.cpp @@ -0,0 +1,128 @@ +/* NickServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +class CommandNSSetURL : public Command +{ + public: + CommandNSSetURL(const ci::string &cname) : Command(cname, 0) + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + if (u->Account()->url) + delete [] u->Account()->url; + + if (!params.empty()) + { + u->Account()->url = sstrdup(params[0].c_str()); + notice_lang(Config.s_NickServ, u, NICK_SET_URL_CHANGED, params[0].c_str()); + } + else + { + u->Account()->url = NULL; + notice_lang(Config.s_NickServ, u, NICK_SET_URL_UNSET); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SET_URL); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_URL); + } +}; + +class CommandNSSASetURL : public Command +{ + public: + CommandNSSASetURL(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/url") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + NickCore *nc = findcore(params[0]); + assert(nc); + + const char *param = params.size() > 1 ? params[1].c_str() : NULL; + + if (nc->url) + delete [] nc->url; + + if (param) + { + nc->url = sstrdup(param); + notice_lang(Config.s_NickServ, u, NICK_SASET_URL_CHANGED, nc->display, param); + } + else + { + nc->url = NULL; + notice_lang(Config.s_NickServ, u, NICK_SASET_URL_UNSET, nc->display); + } + + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &) + { + notice_help(Config.s_NickServ, u, NICK_HELP_SASET_URL); + return true; + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_URL); + } +}; + +class NSSetURL : public Module +{ + public: + NSSetURL(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->AddSubcommand(new CommandNSSetURL("URL")); + + c = FindCommand(NickServ, "SASET"); + if (c) + c->AddSubcommand(new CommandNSSASetURL("URL")); + } + + ~NSSetURL() + { + Command *c = FindCommand(NickServ, "SET"); + if (c) + c->DelSubcommand("URL"); + c = FindCommand(NickServ, "SASET"); + if (c) + c->DelSubcommand("URL"); + } +}; + +MODULE_INIT(NSSetURL) diff --git a/src/core/ns_status.c b/src/core/ns_status.cpp index 978b1f69f..9695dd4fd 100644 --- a/src/core/ns_status.c +++ b/src/core/ns_status.cpp @@ -56,6 +56,11 @@ class CommandNSStatus : public Command notice_help(Config.s_NickServ, u, NICK_HELP_STATUS); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_STATUS); + } }; class NSStatus : public Module @@ -67,13 +72,7 @@ class NSStatus : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSStatus()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_STATUS); + this->AddCommand(NickServ, new CommandNSStatus()); } }; diff --git a/src/core/ns_suspend.c b/src/core/ns_suspend.cpp index 8a909f151..ef147551a 100644 --- a/src/core/ns_suspend.c +++ b/src/core/ns_suspend.cpp @@ -23,11 +23,10 @@ class CommandNSSuspend : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - NickAlias *na, *na2; + NickAlias *na; User *u2; const char *nick = params[0].c_str(); const char *reason = params[1].c_str(); - int i; if (readonly) { @@ -61,9 +60,10 @@ class CommandNSSuspend : public Command na->nc->UnsetFlag(NI_KILL_QUICK); na->nc->UnsetFlag(NI_KILL_IMMED); - for (i = 0; i < na->nc->aliases.count; ++i) + for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it) { - na2 = static_cast<NickAlias *>(na->nc->aliases.list[i]); + NickAlias *na2 = *it; + if (na2->nc == na->nc) { if (na2->last_quit) @@ -79,7 +79,7 @@ class CommandNSSuspend : public Command } if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used SUSPEND on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used SUSPEND on \2%s\2", u->nick.c_str(), nick); Alog() << Config.s_NickServ << ": " << u->nick << " set SUSPEND for nick " << nick; notice_lang(Config.s_NickServ, u, NICK_SUSPEND_SUCCEEDED, nick); @@ -104,6 +104,11 @@ class CommandNSSuspend : public Command { syntax_error(Config.s_NickServ, u, "SUSPEND", NICK_SUSPEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SUSPEND); + } }; class CommandNSUnSuspend : public Command @@ -147,7 +152,7 @@ class CommandNSUnSuspend : public Command na->nc->UnsetFlag(NI_SUSPENDED); if (Config.WallForbid) - ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used UNSUSPEND on \2%s\2", u->nick.c_str(), nick); + ircdproto->SendGlobops(NickServ, "\2%s\2 used UNSUSPEND on \2%s\2", u->nick.c_str(), nick); Alog() << Config.s_NickServ << ": " << u->nick << " set UNSUSPEND for nick " << nick; notice_lang(Config.s_NickServ, u, NICK_UNSUSPEND_SUCCEEDED, nick); @@ -172,6 +177,11 @@ class CommandNSUnSuspend : public Command { syntax_error(Config.s_NickServ, u, "UNSUSPEND", NICK_UNSUSPEND_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNSUSPEND); + } }; class NSSuspend : public Module @@ -183,15 +193,8 @@ class NSSuspend : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSSuspend()); - this->AddCommand(NICKSERV, new CommandNSUnSuspend()); - - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SUSPEND); - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNSUSPEND); + this->AddCommand(NickServ, new CommandNSSuspend()); + this->AddCommand(NickServ, new CommandNSUnSuspend()); } }; diff --git a/src/core/ns_update.c b/src/core/ns_update.cpp index 739f1dc7e..4ed3b5b77 100644 --- a/src/core/ns_update.c +++ b/src/core/ns_update.cpp @@ -46,6 +46,11 @@ class CommandNSUpdate : public Command notice_help(Config.s_NickServ, u, NICK_HELP_UPDATE); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UPDATE); + } }; class NSUpdate : public Module @@ -56,12 +61,7 @@ class NSUpdate : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(NICKSERV, new CommandNSUpdate()); - ModuleManager::Attach(I_OnNickServHelp, this); - } - void OnNickServHelp(User *u) - { - notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UPDATE); + this->AddCommand(NickServ, new CommandNSUpdate()); } }; diff --git a/src/core/os_akill.c b/src/core/os_akill.c deleted file mode 100644 index a83b0aa98..000000000 --- a/src/core/os_akill.c +++ /dev/null @@ -1,409 +0,0 @@ -/* OperServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -int akill_view_callback(SList *slist, int number, void *item, va_list args); -int akill_list_callback(SList *slist, int number, void *item, va_list args); -int akill_view(int number, Akill *ak, User *u, int *sent_header); -int akill_list(int number, Akill *ak, User *u, int *sent_header); - -static int akill_del_callback(SList *slist, void *item, va_list args) -{ - User *u = va_arg(args, User *); - FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(item))); - return 1; -} - -class CommandOSAKill : public Command -{ - private: - CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) - { - int deleted = 0; - unsigned last_param = 2; - const char *expiry, *mask; - char reason[BUFSIZE]; - time_t expires; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - if (mask && *mask == '+') - { - expiry = mask; - mask = params.size() > 2 ? params[2].c_str() : NULL; - last_param = 3; - } - else - expiry = NULL; - - expires = expiry ? dotime(expiry) : Config.AutokillExpiry; - /* If the expiry given does not contain a final letter, it's in days, - * said the doc. Ah well. - */ - if (expiry && isdigit(expiry[strlen(expiry) - 1])) - expires *= 86400; - /* Do not allow less than a minute expiry time */ - if (expires != 0 && expires < 60) - { - notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); - return MOD_CONT; - } - else if (expires > 0) - expires += time(NULL); - - if (params.size() <= last_param) - { - this->OnSyntaxError(u, "ADD"); - return MOD_CONT; - } - snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); - if (mask && *reason) { - /* We first do some sanity check on the proposed mask. */ - if (strchr(mask, '!')) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_NICK); - return MOD_CONT; - } - - if (!strchr(mask, '@')) - { - notice_lang(Config.s_OperServ, u, BAD_USERHOST_MASK); - return MOD_CONT; - } - - if (mask && strspn(mask, "~@.*?") == strlen(mask)) - { - notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask); - return MOD_CONT; - } - - std::string realreason; - if (Config.AddAkiller) - realreason = "[" + u->nick + "] " + std::string(reason); - else - realreason = reason; - - deleted = add_akill(u, mask, u->nick.c_str(), expires, realreason.c_str()); - if (deleted < 0) - return MOD_CONT; - else if (deleted) - notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, deleted); - notice_lang(Config.s_OperServ, u, OPER_AKILL_ADDED, mask); - - if (Config.WallOSAkill) - { - char buf[128]; - - if (!expires) - strcpy(buf, "does not expire"); - else - { - int wall_expiry = expires - time(NULL); - const char *s = NULL; - - if (wall_expiry >= 86400) - { - wall_expiry /= 86400; - s = "day"; - } - else if (wall_expiry >= 3600) - { - wall_expiry /= 3600; - s = "hour"; - } - else if (wall_expiry >= 60) - { - wall_expiry /= 60; - s = "minute"; - } - - snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); - } - - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, realreason.c_str(), buf); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - } - else - this->OnSyntaxError(u, "ADD"); - - return MOD_CONT; - } - - CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res = 0; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask) - { - this->OnSyntaxError(u, "DEL"); - return MOD_CONT; - } - - if (!akills.count) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); - return MOD_CONT; - } - - if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) - { - /* Deleting a range */ - res = slist_delete_range(&akills, mask, akill_del_callback, u); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); - return MOD_CONT; - } - else if (res == 1) - notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE); - else - notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, res); - } - else - { - if ((res = slist_indexof(&akills, const_cast<void *>(static_cast<const void *>(mask)))) == -1) // XXX: possibly unsafe cast - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask); - return MOD_CONT; - } - - FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(akills.list[res]))); - - slist_delete(&akills, res); - notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - return MOD_CONT; - } - - CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!akills.count) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&akills, mask, &akill_list_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); - return MOD_CONT; - } - else - notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill"); - } - else - { - int i; - char amask[BUFSIZE]; - - for (i = 0; i < akills.count; ++i) - { - snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host); - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - akill_list(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); - else - notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill"); - } - - return MOD_CONT; - } - - CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!akills.count) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&akills, mask, &akill_view_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char amask[BUFSIZE]; - - for (i = 0; i < akills.count; ++i) - { - snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host); - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - akill_view(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); - } - - return MOD_CONT; - } - - CommandReturn DoClear(User *u) - { - FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, NULL)); - slist_clear(&akills, 1); - notice_lang(Config.s_OperServ, u, OPER_AKILL_CLEAR); - - return MOD_CONT; - } - public: - CommandOSAKill() : Command("AKILL", 1, 4, "operserv/akill") - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - ci::string cmd = params[0]; - - if (cmd == "ADD") - return this->DoAdd(u, params); - else if (cmd == "DEL") - return this->DoDel(u, params); - else if (cmd == "LIST") - return this->DoList(u, params); - else if (cmd == "VIEW") - return this->DoView(u, params); - else if (cmd == "CLEAR") - return this->DoClear(u); - else - this->OnSyntaxError(u, ""); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_OperServ, u, OPER_HELP_AKILL); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX); - } -}; - -class OSAKill : public Module -{ - public: - OSAKill(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSAKill()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_AKILL); - } -}; - -int akill_view(int number, Akill *ak, User *u, int *sent_header) -{ - char mask[BUFSIZE]; - char timebuf[32], expirebuf[256]; - struct tm tm; - - if (!ak) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER); - *sent_header = 1; - } - - snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host); - tm = *localtime(&ak->seton); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - expire_left(u->Account(), expirebuf, sizeof(expirebuf), ak->expires); - notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, number, mask, ak->by, timebuf, expirebuf, ak->reason); - - return 1; -} - -/* Lists an AKILL entry, prefixing it with the header if needed */ -int akill_list_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return akill_list(number, static_cast<Akill *>(item), u, sent_header); -} - -/* Callback for enumeration purposes */ -int akill_view_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return akill_view(number, static_cast<Akill *>(item), u, sent_header); -} - -/* Lists an AKILL entry, prefixing it with the header if needed */ -int akill_list(int number, Akill *ak, User *u, int *sent_header) -{ - char mask[BUFSIZE]; - - if (!ak) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER); - *sent_header = 1; - } - - snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host); - notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, number, mask, ak->reason); - - return 1; -} - -MODULE_INIT(OSAKill) diff --git a/src/core/os_akill.cpp b/src/core/os_akill.cpp new file mode 100644 index 000000000..fd840cd5c --- /dev/null +++ b/src/core/os_akill.cpp @@ -0,0 +1,402 @@ +/* OperServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class AkillDelCallback : public NumberList +{ + User *u; + unsigned Deleted; + public: + AkillDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0) + { + } + + ~AkillDelCallback() + { + if (!Deleted) + notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); + else if (Deleted == 1) + notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE); + else + notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, Deleted); + } + + void HandleNumber(unsigned Number) + { + XLine *x = SGLine->GetEntry(Number - 1); + + if (!x) + return; + + ++Deleted; + DoDel(u, x); + } + + static void DoDel(User *u, XLine *x) + { + SGLine->DelXLine(x); + } +}; + +class AkillListCallback : public NumberList +{ + protected: + User *u; + bool SentHeader; + public: + AkillListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false) + { + } + + ~AkillListCallback() + { + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); + else + notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill"); + } + + void HandleNumber(unsigned Number) + { + XLine *x = SGLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER); + } + + DoList(u, x, Number); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str()); + } +}; + +class AkillViewCallback : public AkillListCallback +{ + public: + AkillViewCallback(User *_u, const std::string &numlist) : AkillListCallback(_u, numlist) + { + } + + void HandleNumber(unsigned Number) + { + XLine *x = SGLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER); + } + + DoList(u, x, Number); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + char timebuf[32], expirebuf[256]; + struct tm tm; + + tm = *localtime(&x->Created); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires); + + notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str()); + } +}; + +class CommandOSAKill : public Command +{ + private: + CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) + { + unsigned last_param = 2; + const char *expiry, *mask; + char reason[BUFSIZE]; + time_t expires; + + mask = params.size() > 1 ? params[1].c_str() : NULL; + if (mask && *mask == '+') + { + expiry = mask; + mask = params.size() > 2 ? params[2].c_str() : NULL; + last_param = 3; + } + else + expiry = NULL; + + expires = expiry ? dotime(expiry) : Config.AutokillExpiry; + /* If the expiry given does not contain a final letter, it's in days, + * said the doc. Ah well. + */ + if (expiry && isdigit(expiry[strlen(expiry) - 1])) + expires *= 86400; + /* Do not allow less than a minute expiry time */ + if (expires != 0 && expires < 60) + { + notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); + return MOD_CONT; + } + else if (expires > 0) + expires += time(NULL); + + if (params.size() <= last_param) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); + if (mask && *reason) + { + XLine *x = SGLine->Add(OperServ, u, mask, expires, reason); + + if (!x) + return MOD_CONT; + + notice_lang(Config.s_OperServ, u, OPER_AKILL_ADDED, mask); + + if (Config.WallOSAkill) + { + char buf[128]; + + if (!expires) + strcpy(buf, "does not expire"); + else + { + int wall_expiry = expires - time(NULL); + const char *s = NULL; + + if (wall_expiry >= 86400) + { + wall_expiry /= 86400; + s = "day"; + } + else if (wall_expiry >= 3600) + { + wall_expiry /= 3600; + s = "hour"; + } + else if (wall_expiry >= 60) + { + wall_expiry /= 60; + s = "minute"; + } + + snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); + } + + ircdproto->SendGlobops(OperServ, "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, reason, buf); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + } + else + this->OnSyntaxError(u, "ADD"); + + return MOD_CONT; + } + + CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) + { + const ci::string mask = params.size() > 1 ? params[0] : ""; + + if (mask.empty()) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + if (SGLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); + return MOD_CONT; + } + + if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkillDelCallback(u, mask.c_str()))->Process(); + else + { + XLine *x = SGLine->HasEntry(mask); + + if (!x) + { + notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask.c_str()); + return MOD_CONT; + } + + FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, x)); + + AkillDelCallback::DoDel(u, x); + notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask.c_str()); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + return MOD_CONT; + } + + CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) + { + if (SGLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkillListCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SGLine->GetCount(); ++i) + { + XLine *x = SGLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER); + } + + AkillListCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); + else + notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill"); + } + + return MOD_CONT; + } + + CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) + { + if (SGLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new AkillViewCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SGLine->GetCount(); ++i) + { + XLine *x = SGLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER); + } + + AkillViewCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH); + } + + return MOD_CONT; + } + + CommandReturn DoClear(User *u) + { + FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, NULL)); + SGLine->Clear(); + notice_lang(Config.s_OperServ, u, OPER_AKILL_CLEAR); + + return MOD_CONT; + } + public: + CommandOSAKill() : Command("AKILL", 1, 4, "operserv/akill") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ci::string cmd = params[0]; + + if (cmd == "ADD") + return this->DoAdd(u, params); + else if (cmd == "DEL") + return this->DoDel(u, params); + else if (cmd == "LIST") + return this->DoList(u, params); + else if (cmd == "VIEW") + return this->DoView(u, params); + else if (cmd == "CLEAR") + return this->DoClear(u); + else + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_OperServ, u, OPER_HELP_AKILL); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_AKILL); + } +}; + +class OSAKill : public Module +{ + public: + OSAKill(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + this->AddCommand(OperServ, new CommandOSAKill()); + } +}; + +MODULE_INIT(OSAKill) diff --git a/src/core/os_chankill.c b/src/core/os_chankill.cpp index e945728f7..033bf380d 100644 --- a/src/core/os_chankill.c +++ b/src/core/os_chankill.cpp @@ -26,7 +26,6 @@ class CommandOSChanKill : public Command const char *expiry, *channel; char reason[BUFSIZE]; time_t expires; - char *mask = new char[Config.UserLen + Config.HostLen + 2]; unsigned last_param = 1; Channel *c; @@ -46,7 +45,6 @@ class CommandOSChanKill : public Command if (expires != 0 && expires < 60) { notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); - delete [] mask; return MOD_CONT; } else if (expires > 0) @@ -55,7 +53,6 @@ class CommandOSChanKill : public Command if (params.size() <= last_param) { this->OnSyntaxError(u, ""); - delete [] mask; return MOD_CONT; } snprintf(reason, sizeof(reason), "%s%s", params[last_param].c_str(), (params.size() > last_param + 1 ? params[last_param + 1].c_str() : "")); @@ -77,18 +74,15 @@ class CommandOSChanKill : public Command if (is_oper(uc->user)) continue; - strlcpy(mask, "*@", Config.UserLen + Config.HostLen + 2); /* Use *@" for the akill's, */ - strlcat(mask, uc->user->host, Config.UserLen + Config.HostLen + 2); - add_akill(NULL, mask, Config.s_OperServ, expires, realreason.c_str()); - check_akill(uc->user->nick.c_str(), uc->user->GetIdent().c_str(), uc->user->host, NULL, NULL); + SGLine->Add(OperServ, u, ci::string("*@") + uc->user->host, expires, realreason); + SGLine->Check(uc->user); } if (Config.WallOSAkill) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used CHANKILL on %s (%s)", u->nick.c_str(), channel, realreason.c_str()); + ircdproto->SendGlobops(OperServ, "%s used CHANKILL on %s (%s)", u->nick.c_str(), channel, realreason.c_str()); } else notice_lang(Config.s_OperServ, u, CHAN_X_NOT_IN_USE, channel); } - delete [] mask; return MOD_CONT; } @@ -102,6 +96,11 @@ class CommandOSChanKill : public Command { syntax_error(Config.s_OperServ, u, "CHANKILL", OPER_CHANKILL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANKILL); + } }; class OSChanKill : public Module @@ -113,13 +112,7 @@ class OSChanKill : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSChanKill()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANKILL); + this->AddCommand(OperServ, new CommandOSChanKill()); } }; diff --git a/src/core/os_chanlist.c b/src/core/os_chanlist.cpp index 48846255a..eb8c32e6a 100644 --- a/src/core/os_chanlist.c +++ b/src/core/os_chanlist.cpp @@ -38,9 +38,9 @@ class CommandOSChanList : public Command { notice_lang(Config.s_OperServ, u, OPER_CHANLIST_HEADER_USER, u2->nick.c_str()); - for (UChannelList::iterator it = u2->chans.begin(); it != u2->chans.end(); ++it) + for (UChannelList::iterator uit = u2->chans.begin(); uit != u2->chans.end(); ++uit) { - ChannelContainer *cc = *it; + ChannelContainer *cc = *uit; if (!Modes.empty()) { @@ -56,27 +56,24 @@ class CommandOSChanList : public Command } else { - int i; - Channel *c; - notice_lang(Config.s_OperServ, u, OPER_CHANLIST_HEADER); - for (i = 0; i < 1024; ++i) + for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit) { - for (c = chanlist[i]; c; c = c->next) + Channel *c = cit->second; + + if (pattern && !Anope::Match(c->name, pattern, false)) + continue; + if (!Modes.empty()) { - if (pattern && !Anope::Match(c->name, pattern, false)) - continue; - if (!Modes.empty()) + for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) { - for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) - { - if (!c->HasMode(*it)) - continue; - } + if (!c->HasMode(*it)) + continue; } - notice_lang(Config.s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), chan_get_modes(c, 1, 1), c->topic ? c->topic : ""); } + + notice_lang(Config.s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), chan_get_modes(c, 1, 1), c->topic ? c->topic : ""); } } @@ -89,6 +86,11 @@ class CommandOSChanList : public Command notice_help(Config.s_OperServ, u, OPER_HELP_CHANLIST); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANLIST); + } }; class OSChanList : public Module @@ -100,13 +102,7 @@ class OSChanList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSChanList()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANLIST); + this->AddCommand(OperServ, new CommandOSChanList()); } }; diff --git a/src/core/os_clearmodes.c b/src/core/os_clearmodes.cpp index 8d50b92e5..b5ebba938 100644 --- a/src/core/os_clearmodes.c +++ b/src/core/os_clearmodes.cpp @@ -52,7 +52,7 @@ class CommandOSClearModes : public Command } if (Config.WallOSClearmodes) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used CLEARMODES%s on %s", u->nick.c_str(), all ? " ALL" : "", chan); + ircdproto->SendGlobops(OperServ, "%s used CLEARMODES%s on %s", u->nick.c_str(), all ? " ALL" : "", chan); if (all) { /* Clear mode +o */ @@ -166,6 +166,11 @@ class CommandOSClearModes : public Command { syntax_error(Config.s_OperServ, u, "CLEARMODES", OPER_CLEARMODES_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CLEARMODES); + } }; class OSClearModes : public Module @@ -177,13 +182,7 @@ class OSClearModes : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSClearModes()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CLEARMODES); + this->AddCommand(OperServ, new CommandOSClearModes()); } }; diff --git a/src/core/os_defcon.c b/src/core/os_defcon.cpp index 403ac1281..caf2836fe 100644 --- a/src/core/os_defcon.c +++ b/src/core/os_defcon.cpp @@ -36,7 +36,7 @@ class DefConTimeout : public Timer Config.DefConLevel = level; FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level)); Alog() << "Defcon level timeout, returning to lvl " << level; - ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_DEFCON_WALL), Config.s_OperServ, level); + ircdproto->SendGlobops(OperServ, getstring(OPER_DEFCON_WALL), Config.s_OperServ, level); if (Config.GlobalOnDefcon) { @@ -95,7 +95,7 @@ class CommandOSDEFCON : public Command notice_lang(Config.s_OperServ, u, OPER_DEFCON_CHANGED, Config.DefConLevel); defcon_sendlvls(u); Alog() << "Defcon level changed to " << newLevel << " by Oper " << u->nick; - ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_DEFCON_WALL), u->nick.c_str(), newLevel); + ircdproto->SendGlobops(OperServ, getstring(OPER_DEFCON_WALL), u->nick.c_str(), newLevel); /* Global notice the user what is happening. Also any Message that the Admin would like to add. Set in config file. */ if (Config.GlobalOnDefcon) @@ -125,6 +125,11 @@ class CommandOSDEFCON : public Command { syntax_error(Config.s_OperServ, u, "DEFCON", OPER_DEFCON_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_DEFCON); + } }; class OSDEFCON : public Module @@ -141,33 +146,24 @@ class OSDEFCON : public Module throw ModuleException("Invalid configuration settings"); } - Implementation i[] = { I_OnOperServHelp, I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate }; - ModuleManager::Attach(i, this, 9); + Implementation i[] = { I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate }; + ModuleManager::Attach(i, this, 8); - this->AddCommand(OPERSERV, new CommandOSDEFCON()); + this->AddCommand(OperServ, new CommandOSDEFCON()); defconParseModeString(Config.DefConChanModes); } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_DEFCON); - } - EventReturn OnPreUserConnect(User *u) { - std::string mask; - - if (u && is_sync(u->server) && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(u->server->name)) + if (u->server->IsSynced() && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined()) { if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS)) { - mask = "*@" + std::string(u->host); - Alog() << "DEFCON: adding akill for " << mask; - add_akill(NULL, mask.c_str(), Config.s_OperServ, - time(NULL) + Config.DefConAKILL, - Config.DefConAkillReason ? Config.DefConAkillReason : - "DEFCON AKILL"); + Alog() << "DEFCON: adding akill for *@" << u->host; + XLine *x = SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.DefConAKILL, Config.DefConAkillReason ? Config.DefConAkillReason : "DEFCON AKILL"); + if (x) + x->By = Config.s_OperServ; } if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS)) @@ -185,7 +181,7 @@ class OSDEFCON : public Module if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesOff.HasFlag(Name)) { - c->RemoveMode(findbot(Config.s_OperServ), Name, param); + c->RemoveMode(OperServ, Name, param); return EVENT_STOP; } @@ -201,12 +197,12 @@ class OSDEFCON : public Module { std::string param; - if (GetDefConParam(Name, ¶m)) + if (GetDefConParam(Name, param)) { - c->SetMode(findbot(Config.s_OperServ), Name, param); + c->SetMode(OperServ, Name, param); } else - c->SetMode(findbot(Config.s_OperServ), Name); + c->SetMode(OperServ, Name); return EVENT_STOP; @@ -215,7 +211,7 @@ class OSDEFCON : public Module return EVENT_CONTINUE; } - EventReturn OnPreCommandRun(const std::string &service, User *u, const char *cmd, Command *c) + EventReturn OnPreCommandRun(User *u, BotInfo *bi, const ci::string &command, const ci::string &message, Command *c) { if (!c) { @@ -226,7 +222,7 @@ class OSDEFCON : public Module { if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY)) { - notice_lang(service, u, OPER_DEFCON_DENIED); + notice_lang(bi->nick.c_str(), u, OPER_DEFCON_DENIED); } return EVENT_STOP; @@ -295,18 +291,16 @@ class OSDEFCON : public Module if (session && session->count > Config.DefConSessionLimit) { if (Config.SessionLimitExceeded) - ircdproto->SendMessage(findbot(Config.s_OperServ), u->nick.c_str(), Config.SessionLimitExceeded, u->host); + ircdproto->SendMessage(OperServ, u->nick.c_str(), Config.SessionLimitExceeded, u->host); if (Config.SessionLimitDetailsLoc) - ircdproto->SendMessage(findbot(Config.s_OperServ), u->nick.c_str(), "%s", Config.SessionLimitDetailsLoc); + ircdproto->SendMessage(OperServ, u->nick.c_str(), "%s", Config.SessionLimitDetailsLoc); kill_user(Config.s_OperServ, u->nick, "Session limit exceeded"); session->hits++; if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill) { - char akillmask[BUFSIZE]; - snprintf(akillmask, sizeof(akillmask), "*@%s", u->host); - add_akill(NULL, akillmask, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded"); - ircdproto->SendGlobops(findbot(Config.s_OperServ), "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); + SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded"); + ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host); } } } @@ -332,7 +326,7 @@ class OSDEFCON : public Module { if (CheckDefCon(DEFCON_FORCE_CHAN_MODES)) { - c->SetModes(findbot(Config.s_OperServ), false, Config.DefConChanModes); + c->SetModes(OperServ, false, Config.DefConChanModes); } } }; @@ -375,22 +369,22 @@ void runDefCon() if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-') { Alog() << "DEFCON: setting " << Config.DefConChanModes << " on all channels"; - DefConModesSet = 1; - MassChannelModes(findbot(Config.s_OperServ), Config.DefConChanModes); + DefConModesSet = true; + MassChannelModes(OperServ, Config.DefConChanModes); } } } else { - if (Config.DefConChanModes && (DefConModesSet != 0)) + if (Config.DefConChanModes && DefConModesSet) { if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-') { - DefConModesSet = 0; + DefConModesSet = false; if ((newmodes = defconReverseModes(Config.DefConChanModes))) { Alog() << "DEFCON: setting " << newmodes << " on all channels"; - MassChannelModes(findbot(Config.s_OperServ), newmodes); + MassChannelModes(OperServ, newmodes); delete [] newmodes; } } diff --git a/src/core/os_global.c b/src/core/os_global.cpp index 4c2c81e22..df62f753f 100644 --- a/src/core/os_global.c +++ b/src/core/os_global.cpp @@ -26,7 +26,7 @@ class CommandOSGlobal : public Command const char *msg = params[0].c_str(); if (Config.WallOSGlobal) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 just used GLOBAL command.", u->nick.c_str()); + ircdproto->SendGlobops(OperServ, "\2%s\2 just used GLOBAL command.", u->nick.c_str()); oper_global(const_cast<char *>(u->nick.c_str()), "%s", msg); return MOD_CONT; } @@ -41,6 +41,11 @@ class CommandOSGlobal : public Command { syntax_error(Config.s_OperServ, u, "GLOBAL", OPER_GLOBAL_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_GLOBAL); + } }; class OSGlobal : public Module @@ -52,13 +57,7 @@ class OSGlobal : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSGlobal()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_GLOBAL); + this->AddCommand(OperServ, new CommandOSGlobal()); } }; diff --git a/src/core/os_help.c b/src/core/os_help.cpp index baeb5a45f..d6f9001b4 100644 --- a/src/core/os_help.c +++ b/src/core/os_help.cpp @@ -23,14 +23,15 @@ class CommandOSHelp : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - mod_help_cmd(Config.s_OperServ, u, OPERSERV, params[0].c_str()); + mod_help_cmd(OperServ, u, params[0].c_str()); return MOD_CONT; } void OnSyntaxError(User *u, const ci::string &subcommand) { notice_help(Config.s_OperServ, u, OPER_HELP); - FOREACH_MOD(I_OnOperServHelp, OnOperServHelp(u)); + for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it) + it->second->OnServHelp(u); notice_help(Config.s_OperServ, u, OPER_HELP_LOGGED); } }; @@ -43,7 +44,7 @@ class OSHelp : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSHelp()); + this->AddCommand(OperServ, new CommandOSHelp()); } }; diff --git a/src/core/os_ignore.c b/src/core/os_ignore.cpp index 335fa8d63..f852a36b8 100644 --- a/src/core/os_ignore.c +++ b/src/core/os_ignore.cpp @@ -127,6 +127,11 @@ class CommandOSIgnore : public Command { syntax_error(Config.s_OperServ, u, "IGNORE", OPER_IGNORE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_IGNORE); + } }; class OSIgnore : public Module @@ -137,17 +142,12 @@ class OSIgnore : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSIgnore()); + this->AddCommand(OperServ, new CommandOSIgnore()); - Implementation i[] = { I_OnOperServHelp, I_OnDatabaseRead, I_OnDatabaseWrite }; - ModuleManager::Attach(i, this, 3); + Implementation i[] = { I_OnDatabaseRead, I_OnDatabaseWrite }; + ModuleManager::Attach(i, this, 2); } - - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_IGNORE); - } - + EventReturn OnDatabaseRead(const std::vector<std::string> ¶ms) { std::string buf; diff --git a/src/core/os_jupe.c b/src/core/os_jupe.cpp index 9af3d3176..7fedb968c 100644 --- a/src/core/os_jupe.c +++ b/src/core/os_jupe.cpp @@ -25,22 +25,24 @@ class CommandOSJupe : public Command { const char *jserver = params[0].c_str(); const char *reason = params.size() > 1 ? params[1].c_str() : NULL; - Server *server = findserver(servlist, jserver); + Server *server = Server::Find(jserver); if (!isValidHost(jserver, 3)) notice_lang(Config.s_OperServ, u, OPER_JUPE_HOST_ERROR); - else if (server && (server->HasFlag(SERVER_ISME) || server->HasFlag(SERVER_ISUPLINK))) + else if (server && (server == Me || server == Me->GetUplink())) notice_lang(Config.s_OperServ, u, OPER_JUPE_INVALID_SERVER); - else { + else + { char rbuf[256]; snprintf(rbuf, sizeof(rbuf), "Juped by %s%s%s", u->nick.c_str(), reason ? ": " : "", reason ? reason : ""); - if (findserver(servlist, jserver)) + if (server) ircdproto->SendSquit(jserver, rbuf); - Server *juped_server = new_server(me_server, jserver, rbuf, SERVER_JUPED, ircd->ts6 ? ts6_sid_retrieve() : ""); + Server *juped_server = new Server(Me, jserver, 0, rbuf, ircd->ts6 ? ts6_sid_retrieve() : ""); + juped_server->SetFlag(SERVER_JUPED); ircdproto->SendServer(juped_server); if (Config.WallOSJupe) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used JUPE on \2%s\2", u->nick.c_str(), jserver); + ircdproto->SendGlobops(OperServ, "\2%s\2 used JUPE on \2%s\2", u->nick.c_str(), jserver); } return MOD_CONT; } @@ -55,6 +57,11 @@ class CommandOSJupe : public Command { syntax_error(Config.s_OperServ, u, "JUPE", OPER_JUPE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_JUPE); + } }; class OSJupe : public Module @@ -66,13 +73,7 @@ class OSJupe : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSJupe()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_JUPE); + this->AddCommand(OperServ, new CommandOSJupe()); } }; diff --git a/src/core/os_kick.c b/src/core/os_kick.cpp index 803a2c970..f4fb4f7e5 100644 --- a/src/core/os_kick.c +++ b/src/core/os_kick.cpp @@ -43,9 +43,9 @@ class CommandOSKick : public Command return MOD_CONT; } - c->Kick(findbot(Config.s_OperServ), u2, "%s (%s)", u->nick.c_str(), s); + c->Kick(OperServ, u2, "%s (%s)", u->nick.c_str(), s); if (Config.WallOSKick) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used KICK on %s/%s", u->nick.c_str(), u2->nick.c_str(), chan); + ircdproto->SendGlobops(OperServ, "%s used KICK on %s/%s", u->nick.c_str(), u2->nick.c_str(), chan); return MOD_CONT; } @@ -59,6 +59,11 @@ class CommandOSKick : public Command { syntax_error(Config.s_OperServ, u, "KICK", OPER_KICK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_KICK); + } }; class OSKick : public Module @@ -70,13 +75,7 @@ class OSKick : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSKick()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_KICK); + this->AddCommand(OperServ, new CommandOSKick()); } }; diff --git a/src/core/os_mode.c b/src/core/os_mode.cpp index 0eddcd82b..1f9396169 100644 --- a/src/core/os_mode.c +++ b/src/core/os_mode.cpp @@ -32,10 +32,10 @@ class CommandOSMode : public Command notice_lang(Config.s_OperServ, u, OPER_BOUNCY_MODES_U_LINE); else { - c->SetModes(findbot(Config.s_OperServ), false, modes); + c->SetModes(OperServ, false, modes); if (Config.WallOSMode) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used MODE %s on %s", u->nick.c_str(), modes, chan); + ircdproto->SendGlobops(OperServ, "%s used MODE %s on %s", u->nick.c_str(), modes, chan); } return MOD_CONT; } @@ -50,6 +50,11 @@ class CommandOSMode : public Command { syntax_error(Config.s_OperServ, u, "MODE", OPER_MODE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODE); + } }; class OSMode : public Module @@ -61,13 +66,7 @@ class OSMode : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSMode()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODE); + this->AddCommand(OperServ, new CommandOSMode()); } }; diff --git a/src/core/os_modinfo.c b/src/core/os_modinfo.cpp index 2a1d8a8f8..055d2a136 100644 --- a/src/core/os_modinfo.c +++ b/src/core/os_modinfo.cpp @@ -14,7 +14,7 @@ #include "module.h" -int showModuleCmdLoaded(CommandHash *cmdList, const char *mod_name, User *u); +static int showModuleCmdLoaded(BotInfo *bi, const ci::string &mod_name, User *u); class CommandOSModInfo : public Command { @@ -25,30 +25,27 @@ class CommandOSModInfo : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - const char *file = params[0].c_str(); + const std::string file = params[0].c_str(); struct tm tm; char timebuf[64]; - Module *m; - int idx = 0; - m = findModule(file); + Module *m = FindModule(file.c_str()); if (m) { tm = *localtime(&m->created); strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm); notice_lang(Config.s_OperServ, u, OPER_MODULE_INFO_LIST, m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "?", timebuf); - for (idx = 0; idx < MAX_CMD_HASH; ++idx) - { - showModuleCmdLoaded(HOSTSERV[idx], m->name.c_str(), u); - showModuleCmdLoaded(OPERSERV[idx], m->name.c_str(), u); - showModuleCmdLoaded(NICKSERV[idx], m->name.c_str(), u); - showModuleCmdLoaded(CHANSERV[idx], m->name.c_str(), u); - showModuleCmdLoaded(BOTSERV[idx], m->name.c_str(), u); - showModuleCmdLoaded(MEMOSERV[idx], m->name.c_str(), u); - } + + showModuleCmdLoaded(HostServ, m->name.c_str(), u); + showModuleCmdLoaded(OperServ, m->name.c_str(), u); + showModuleCmdLoaded(NickServ, m->name.c_str(), u); + showModuleCmdLoaded(ChanServ, m->name.c_str(), u); + showModuleCmdLoaded(BotServ, m->name.c_str(), u); + showModuleCmdLoaded(MemoServ, m->name.c_str(), u); } else - notice_lang(Config.s_OperServ, u, OPER_MODULE_NO_INFO, file); + notice_lang(Config.s_OperServ, u, OPER_MODULE_NO_INFO, file.c_str()); + return MOD_CONT; } @@ -62,6 +59,11 @@ class CommandOSModInfo : public Command { syntax_error(Config.s_OperServ, u, "MODINFO", OPER_MODULE_INFO_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODINFO); + } }; class OSModInfo : public Module @@ -72,31 +74,25 @@ class OSModInfo : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSModInfo()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODINFO); + this->AddCommand(OperServ, new CommandOSModInfo()); } }; -int showModuleCmdLoaded(CommandHash *cmdList, const char *mod_name, User *u) +static int showModuleCmdLoaded(BotInfo *bi, const ci::string &mod_name, User *u) { - Command *c; - CommandHash *current; + if (!bi) + return 0; + int display = 0; - for (current = cmdList; current; current = current->next) + for (std::map<ci::string, Command *>::iterator it = bi->Commands.begin(); it != bi->Commands.end(); ++it) { - for (c = current->c; c; c = c->next) + Command *c = it->second; + + if (c->module && c->module->name == mod_name) { - if (c->mod_name && !stricmp(c->mod_name, mod_name)) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_CMD_LIST, c->service, c->name.c_str()); - ++display; - } + notice_lang(Config.s_OperServ, u, OPER_MODULE_CMD_LIST, c->service, c->name.c_str()); + ++display; } } return display; diff --git a/src/core/os_modlist.c b/src/core/os_modlist.cpp index 3619a466b..a8ab244fd 100644 --- a/src/core/os_modlist.c +++ b/src/core/os_modlist.cpp @@ -23,7 +23,6 @@ class CommandOSModList : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - int idx; int count = 0; int showCore = 0; int showThird = 1; @@ -34,7 +33,6 @@ class CommandOSModList : public Command int showDB = 1; ci::string param = params.size() ? params[0] : ""; - ModuleHash *current = NULL; char core[] = "Core"; char third[] = "3rd"; @@ -120,61 +118,60 @@ class CommandOSModList : public Command notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST_HEADER); - for (idx = 0; idx != MAX_CMD_HASH; ++idx) + for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it) { - for (current = MODULE_HASH[idx]; current; current = current->next) + Module *m = *it; + + switch (m->type) { - switch (current->m->type) - { - case CORE: - if (showCore) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), core); - ++count; - } - break; - case THIRD: - if (showThird) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), third); - ++count; - } - break; - case PROTOCOL: - if (showProto) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), proto); - ++count; - } - break; - case SUPPORTED: - if (showSupported) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), supported); - ++count; - } - break; - case QATESTED: - if (showQA) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), qa); - ++count; - } - break; - case ENCRYPTION: - if (showEnc) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), enc); - ++count; - } - break; - case DATABASE: - if (showDB) - { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), db); - ++count; - } - } + case CORE: + if (showCore) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), core); + ++count; + } + break; + case THIRD: + if (showThird) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), third); + ++count; + } + break; + case PROTOCOL: + if (showProto) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), proto); + ++count; + } + break; + case SUPPORTED: + if (showSupported) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), supported); + ++count; + } + break; + case QATESTED: + if (showQA) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), qa); + ++count; + } + break; + case ENCRYPTION: + if (showEnc) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), enc); + ++count; + } + break; + case DATABASE: + if (showDB) + { + notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), db); + ++count; + } } } if (!count) @@ -190,6 +187,11 @@ class CommandOSModList : public Command notice_help(Config.s_OperServ, u, OPER_HELP_MODLIST); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLIST); + } }; class OSModList : public Module @@ -201,13 +203,7 @@ class OSModList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSModList()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLIST); + this->AddCommand(OperServ, new CommandOSModList()); } }; diff --git a/src/core/os_modload.c b/src/core/os_modload.cpp index 870c7b0a4..9265c8e72 100644 --- a/src/core/os_modload.c +++ b/src/core/os_modload.cpp @@ -23,19 +23,19 @@ class CommandOSModLoad : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - const char *name = params[0].c_str(); + const std::string mname = params[0].c_str(); - Module *m = findModule(name); + Module *m = FindModule(mname); if (m) { - notice_lang(Config.s_OperServ, u, OPER_MODULE_ALREADY_LOADED, name); + notice_lang(Config.s_OperServ, u, OPER_MODULE_ALREADY_LOADED, mname.c_str()); return MOD_CONT; } - int status = ModuleManager::LoadModule(name, u); + int status = ModuleManager::LoadModule(mname, u); if (status != MOD_ERR_OK) { - notice_lang(Config.s_OperServ, u, OPER_MODULE_LOAD_FAIL, name); + notice_lang(Config.s_OperServ, u, OPER_MODULE_LOAD_FAIL, mname.c_str()); } return MOD_CONT; @@ -51,6 +51,11 @@ class CommandOSModLoad : public Command { syntax_error(Config.s_OperServ, u, "MODLOAD", OPER_MODULE_LOAD_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLOAD); + } }; class OSModLoad : public Module @@ -63,13 +68,7 @@ class OSModLoad : public Module this->SetType(CORE); this->SetPermanent(true); - this->AddCommand(OPERSERV, new CommandOSModLoad()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLOAD); + this->AddCommand(OperServ, new CommandOSModLoad()); } }; diff --git a/src/core/os_modunload.c b/src/core/os_modunload.cpp index 6f6de9e81..77ef413ca 100644 --- a/src/core/os_modunload.c +++ b/src/core/os_modunload.cpp @@ -23,22 +23,22 @@ class CommandOSModUnLoad : public Command CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) { - const char *name = params[0].c_str(); + const std::string mname = params[0].c_str(); int status; - Module *m = findModule(name); + Module *m = FindModule(mname); if (!m) { - notice_lang(Config.s_OperServ, u, OPER_MODULE_ISNT_LOADED, name); + notice_lang(Config.s_OperServ, u, OPER_MODULE_ISNT_LOADED, mname.c_str()); return MOD_CONT; } - Alog() << "Trying to unload module [" << name << "]"; + Alog() << "Trying to unload module [" << mname << "]"; status = ModuleManager::UnloadModule(m, u); if (status != MOD_ERR_OK) - notice_lang(Config.s_OperServ, u, OPER_MODULE_REMOVE_FAIL, name); + notice_lang(Config.s_OperServ, u, OPER_MODULE_REMOVE_FAIL, mname.c_str()); return MOD_CONT; } @@ -53,6 +53,11 @@ class CommandOSModUnLoad : public Command { syntax_error(Config.s_OperServ, u, "MODUNLOAD", OPER_MODULE_UNLOAD_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODUNLOAD); + } }; class OSModUnLoad : public Module @@ -65,13 +70,7 @@ class OSModUnLoad : public Module this->SetType(CORE); this->SetPermanent(true); - this->AddCommand(OPERSERV, new CommandOSModUnLoad()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODUNLOAD); + this->AddCommand(OperServ, new CommandOSModUnLoad()); } }; diff --git a/src/core/os_news.c b/src/core/os_news.cpp index 9daf1b443..7be0bc5f7 100644 --- a/src/core/os_news.c +++ b/src/core/os_news.cpp @@ -14,6 +14,8 @@ #include "module.h" +#define lenof(a) (sizeof(a) / sizeof(*(a))) + /* List of messages for each news type. This simplifies message sending. */ #define MSG_SYNTAX 0 @@ -300,7 +302,7 @@ class NewsBase : public Command return MOD_CONT; } public: - NewsBase(const std::string &newstype) : Command(newstype, 1, 2, "operserv/news") + NewsBase(const ci::string &newstype) : Command(newstype, 1, 2, "operserv/news") { } @@ -337,6 +339,11 @@ class CommandOSLogonNews : public NewsBase { syntax_error(Config.s_OperServ, u, "LOGONNEWS", NEWS_LOGON_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_LOGONNEWS); + } }; class CommandOSOperNews : public NewsBase @@ -361,6 +368,11 @@ class CommandOSOperNews : public NewsBase { syntax_error(Config.s_OperServ, u, "OPERNEWS", NEWS_OPER_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OPERNEWS); + } }; class CommandOSRandomNews : public NewsBase @@ -385,6 +397,11 @@ class CommandOSRandomNews : public NewsBase { syntax_error(Config.s_OperServ, u, "RANDOMNEWS", NEWS_RANDOM_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RANDOMNEWS); + } }; class OSNews : public Module @@ -396,12 +413,12 @@ class OSNews : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSLogonNews()); - this->AddCommand(OPERSERV, new CommandOSOperNews()); - this->AddCommand(OPERSERV, new CommandOSRandomNews()); + this->AddCommand(OperServ, new CommandOSLogonNews()); + this->AddCommand(OperServ, new CommandOSOperNews()); + this->AddCommand(OperServ, new CommandOSRandomNews()); - Implementation i[] = { I_OnOperServHelp, I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite }; - ModuleManager::Attach(i, this, 5); + Implementation i[] = { I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite }; + ModuleManager::Attach(i, this, 4); } ~OSNews() @@ -411,13 +428,6 @@ class OSNews : public Module News.clear(); } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_LOGONNEWS); - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OPERNEWS); - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RANDOMNEWS); - } - void OnUserModeSet(User *u, UserModeName Name) { if (Name == UMODE_OPER) diff --git a/src/core/os_noop.c b/src/core/os_noop.cpp index c0fc33161..270373f0c 100644 --- a/src/core/os_noop.c +++ b/src/core/os_noop.cpp @@ -28,8 +28,6 @@ class CommandOSNOOP : public Command if (cmd == "SET") { - User *u2; - User *u3 = NULL; std::string reason; /* Remove the O:lines */ @@ -37,14 +35,16 @@ class CommandOSNOOP : public Command reason = "NOOP command used by " + u->nick; if (Config.WallOSNoOp) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used NOOP on \2%s\2", u->nick.c_str(), server); + ircdproto->SendGlobops(OperServ, "\2%s\2 used NOOP on \2%s\2", u->nick.c_str(), server); notice_lang(Config.s_OperServ, u, OPER_NOOP_SET, server); /* Kill all the IRCops of the server */ - for (u2 = firstuser(); u2; u2 = u3) + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) { - u3 = nextuser(); - if (u2 && is_oper(u2) && u2->server->name && Anope::Match(u2->server->name, server, true)) + User *u2 = it->second; + ++it; + + if (u2 && is_oper(u2) && Anope::Match(u2->server->GetName(), server, true)) kill_user(Config.s_OperServ, u2->nick.c_str(), reason.c_str()); } } @@ -68,6 +68,11 @@ class CommandOSNOOP : public Command { syntax_error(Config.s_OperServ, u, "NOOP", OPER_NOOP_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_NOOP); + } }; class OSNOOP : public Module @@ -79,13 +84,7 @@ class OSNOOP : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSNOOP()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_NOOP); + this->AddCommand(OperServ, new CommandOSNOOP()); } }; diff --git a/src/core/os_oline.c b/src/core/os_oline.cpp index 52f7d7ac0..d0ee5ea96 100644 --- a/src/core/os_oline.c +++ b/src/core/os_oline.cpp @@ -33,16 +33,16 @@ class CommandOSOLine : public Command else if (u2 && flag[0] == '+') { ircdproto->SendSVSO(Config.s_OperServ, nick, flag); - u2->SetMode(findbot(Config.s_OperServ), UMODE_OPER); + u2->SetMode(OperServ, UMODE_OPER); notice_lang(Config.s_OperServ, u2, OPER_OLINE_IRCOP); notice_lang(Config.s_OperServ, u, OPER_OLINE_SUCCESS, flag, nick); - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick); + ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick); } else if (u2 && flag[0] == '-') { ircdproto->SendSVSO(Config.s_OperServ, nick, flag); notice_lang(Config.s_OperServ, u, OPER_OLINE_SUCCESS, flag, nick); - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick); + ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick); } else this->OnSyntaxError(u, ""); @@ -59,6 +59,11 @@ class CommandOSOLine : public Command { syntax_error(Config.s_OperServ, u, "OLINE", OPER_OLINE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OLINE); + } }; class OSOLine : public Module @@ -70,16 +75,10 @@ class OSOLine : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSOLine()); + this->AddCommand(OperServ, new CommandOSOLine()); if (!ircd->omode) throw ModuleException("Your IRCd does not support OMODE."); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OLINE); } }; diff --git a/src/core/os_quit.c b/src/core/os_quit.cpp index 4c6d09587..41703c1b7 100644 --- a/src/core/os_quit.c +++ b/src/core/os_quit.cpp @@ -41,6 +41,11 @@ class CommandOSQuit : public Command notice_help(Config.s_OperServ, u, OPER_HELP_QUIT); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_QUIT); + } }; class OSQuit : public Module @@ -52,13 +57,7 @@ class OSQuit : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSQuit()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_QUIT); + this->AddCommand(OperServ, new CommandOSQuit()); } }; diff --git a/src/core/os_reload.c b/src/core/os_reload.cpp index 10afe2aa7..07fffa94f 100644 --- a/src/core/os_reload.c +++ b/src/core/os_reload.cpp @@ -43,6 +43,11 @@ class CommandOSReload : public Command notice_help(Config.s_OperServ, u, OPER_HELP_RELOAD); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RELOAD); + } }; class OSReload : public Module @@ -54,13 +59,7 @@ class OSReload : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSReload()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RELOAD); + this->AddCommand(OperServ, new CommandOSReload()); } }; diff --git a/src/core/os_restart.c b/src/core/os_restart.cpp index 051b92155..efb5bdada 100644 --- a/src/core/os_restart.c +++ b/src/core/os_restart.cpp @@ -41,6 +41,11 @@ class CommandOSRestart : public Command notice_help(Config.s_OperServ, u, OPER_HELP_RESTART); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RESTART); + } }; class OSRestart : public Module @@ -51,13 +56,7 @@ class OSRestart : public Module this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSRestart()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RESTART); + this->AddCommand(OperServ, new CommandOSRestart()); } }; diff --git a/src/core/os_session.c b/src/core/os_session.cpp index f450cf6a1..34d34fcc4 100644 --- a/src/core/os_session.c +++ b/src/core/os_session.cpp @@ -14,13 +14,127 @@ #include "module.h" +class ExceptionDelCallback : public NumberList +{ + protected: + User *u; + unsigned Deleted; + public: + ExceptionDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0) + { + } + + ~ExceptionDelCallback() + { + if (!Deleted) + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); + else if (Deleted == 1) + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_ONE); + else + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_SEVERAL, Deleted); + } + + virtual void HandleNumber(unsigned Number) + { + if (Number > nexceptions) + return; + + ++Deleted; + + DoDel(u, Number - 1); + } + + static void DoDel(User *u, unsigned index) + { + FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(u, &exceptions[index])); + + delete [] exceptions[index].mask; + delete [] exceptions[index].reason; + --nexceptions; + memmove(exceptions + index, exceptions + index + 1, sizeof(Exception) * (nexceptions - index)); + exceptions = static_cast<Exception *>(srealloc(exceptions, sizeof(Exception) * nexceptions)); + } +}; + +class ExceptionListCallback : public NumberList +{ + protected: + User *u; + bool SentHeader; + public: + ExceptionListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false) + { + } + + virtual void HandleNumber(unsigned Number) + { + if (Number > nexceptions) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD); + } + + DoList(u, Number - 1); + } + + static void DoList(User *u, unsigned index) + { + if (index >= nexceptions) + return; + + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_FORMAT, index + 1, exceptions[index].limit, exceptions[index].mask); + } +}; + +class ExceptionViewCallback : public ExceptionListCallback +{ + public: + ExceptionViewCallback(User *_u, const std::string &numlist) : ExceptionListCallback(_u, numlist) + { + } + + void HandleNumber(unsigned Number) + { + if (Number > nexceptions) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); + } + + DoList(u, Number - 1); + } + + static void DoList(User *u, unsigned index) + { + if (index >= nexceptions) + return; + + char timebuf[32], expirebuf[256]; + struct tm tm; + time_t t = time(NULL); + + tm = *localtime(exceptions[index].time ? &exceptions[index].time : &t); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + + expire_left(u->Account(), expirebuf, sizeof(expirebuf), exceptions[index].expires); + + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_VIEW_FORMAT, index + 1, exceptions[index].mask, exceptions[index].who ? exceptions[index].who : "<unknown>", timebuf, expirebuf, exceptions[index].limit, exceptions[index].reason); + } +}; + class CommandOSSession : public Command { private: CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) { - Session *session; - int mincount, i; + int mincount; const char *param = params[1].c_str(); if ((mincount = atoi(param)) <= 1) @@ -29,13 +143,13 @@ class CommandOSSession : public Command { notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_HEADER, mincount); notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_COLHEAD); - for (i = 0; i < 1024; ++i) + + for (session_map::const_iterator it = SessionList.begin(); it != SessionList.end(); ++it) { - for (session = sessionlist[i]; session; session = session->next) - { - if (session->count >= mincount) - notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host); - } + Session *session = it->second; + + if (session->count >= mincount) + notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host); } } @@ -90,94 +204,12 @@ class CommandOSSession : public Command { syntax_error(Config.s_OperServ, u, "SESSION", OPER_SESSION_LIST_SYNTAX); } -}; -static int exception_del(User *u, const int index) -{ - if (index < 0 || index >= nexceptions) - return 0; - - FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(u, &exceptions[index])); - - delete [] exceptions[index].mask; - delete [] exceptions[index].reason; - --nexceptions; - memmove(exceptions + index, exceptions + index + 1, sizeof(Exception) * (nexceptions - index)); - exceptions = static_cast<Exception *>(srealloc(exceptions, sizeof(Exception) * nexceptions)); - - return 1; -} - -/* We use the "num" property to keep track of the position of each exception - * when deleting using ranges. This is because an exception's position changes - * as others are deleted. The positions will be recalculated once the process - * is complete. -TheShadow - */ - -static int exception_del_callback(User *u, int num, va_list args) -{ - int i; - int *last = va_arg(args, int *); - - *last = num; - for (i = 0; i < nexceptions; ++i) - if (num - 1 == exceptions[i].num) - break; - - if (i < nexceptions) - return exception_del(u, i); - else - return 0; -} - -static int exception_list(User *u, const int index, int *sent_header) -{ - if (index < 0 || index >= nexceptions) - return 0; - if (!*sent_header) { - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD); - *sent_header = 1; - } - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_FORMAT, index + 1, exceptions[index].limit, exceptions[index].mask); - return 1; -} - -static int exception_list_callback(User *u, int num, va_list args) -{ - int *sent_header = va_arg(args, int *); - - return exception_list(u, num - 1, sent_header); -} - -static int exception_view(User *u, const int index, int *sent_header) -{ - char timebuf[32], expirebuf[256]; - struct tm tm; - time_t t = time(NULL); - - if (index < 0 || index >= nexceptions) - return 0; - if (!*sent_header) { - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); - *sent_header = 1; + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SESSION); } - - tm = *localtime(exceptions[index].time ? &exceptions[index].time : &t); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - - expire_left(u->Account(), expirebuf, sizeof(expirebuf), exceptions[index].expires); - - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_VIEW_FORMAT, index + 1, exceptions[index].mask, exceptions[index].who ? exceptions[index].who : "<unknown>", timebuf, expirebuf, exceptions[index].limit, exceptions[index].reason); - return 1; -} - -static int exception_view_callback(User *u, int num, va_list args) -{ - int *sent_header = va_arg(args, int *); - - return exception_view(u, num - 1, sent_header); -} +}; class CommandOSException : public Command { @@ -189,12 +221,6 @@ class CommandOSException : public Command unsigned last_param = 3; int x; - if (nexceptions >= 32767) - { - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_TOO_MANY); - return MOD_CONT; - } - mask = params.size() > 1 ? params[1].c_str() : NULL; if (mask && *mask == '+') { @@ -268,21 +294,7 @@ class CommandOSException : public Command } if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) - { - int count, deleted, last = -1; - deleted = process_numlist(mask, &count, exception_del_callback, u, &last); - if (!deleted) - { - if (count == 1) - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_SUCH_ENTRY, last); - else - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); - } - else if (deleted == 1) - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_ONE); - else - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_SEVERAL, deleted); - } + (new ExceptionDelCallback(u, mask))->Process(); else { int deleted = 0; @@ -291,7 +303,7 @@ class CommandOSException : public Command { if (!stricmp(mask, exceptions[i].mask)) { - exception_del(u, i); + ExceptionDelCallback::DoDel(u, i); notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED, mask); deleted = 1; break; @@ -368,44 +380,67 @@ class CommandOSException : public Command CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) { - int sent_header = 0, i; + int i; expire_exceptions(); const char *mask = params.size() > 1 ? params[1].c_str() : NULL; if (mask && strspn(mask, "1234567890,-") == strlen(mask)) - process_numlist(mask, NULL, exception_list_callback, u, &sent_header); + (new ExceptionListCallback(u, mask))->Process(); else { + bool SentHeader = false; + for (i = 0; i < nexceptions; ++i) { if (!mask || Anope::Match(exceptions[i].mask, mask, false)) - exception_list(u, i, &sent_header); + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD); + } + + ExceptionListCallback::DoList(u, i); + } } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); } - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); return MOD_CONT; } CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) { - int sent_header = 0, i; + int i; expire_exceptions(); const char *mask = params.size() > 1 ? params[1].c_str() : NULL; if (mask && strspn(mask, "1234567890,-") == strlen(mask)) - process_numlist(mask, NULL, exception_view_callback, u, &sent_header); + (new ExceptionViewCallback(u, mask))->Process(); else { + bool SentHeader = false; + for (i = 0; i < nexceptions; ++i) { if (!mask || Anope::Match(exceptions[i].mask, mask, false)) - exception_view(u, i, &sent_header); + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER); + } + + ExceptionViewCallback::DoList(u, i); + } } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); } - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH); return MOD_CONT; } @@ -449,6 +484,11 @@ class CommandOSException : public Command { syntax_error(Config.s_OperServ, u, "EXCEPTION", OPER_EXCEPTION_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_EXCEPTION); + } }; class OSSession : public Module @@ -460,15 +500,8 @@ class OSSession : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSSession()); - this->AddCommand(OPERSERV, new CommandOSException()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SESSION); - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_EXCEPTION); + this->AddCommand(OperServ, new CommandOSSession()); + this->AddCommand(OperServ, new CommandOSException()); } }; diff --git a/src/core/os_set.c b/src/core/os_set.cpp index dea5286d6..d51a13bd6 100644 --- a/src/core/os_set.c +++ b/src/core/os_set.cpp @@ -113,7 +113,7 @@ class CommandOSSet : public Command if (ircd->join2msg) { c = findchan(Config.LogChannel); - ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, c ? c->creation_time : time(NULL)); + ircdproto->SendJoin(Global, Config.LogChannel, c ? c->creation_time : time(NULL)); } LogChan = true; Alog() << "Now sending log messages to " << Config.LogChannel; @@ -123,7 +123,7 @@ class CommandOSSet : public Command { Alog() << "No longer sending log messages to a channel"; if (ircd->join2msg) - ircdproto->SendPart(findbot(Config.s_GlobalNoticer), findchan(Config.LogChannel), NULL); + ircdproto->SendPart(Global, findchan(Config.LogChannel), NULL); LogChan = false; notice_lang(Config.s_OperServ, u, OPER_SET_LOGCHAN_OFF); } @@ -155,14 +155,14 @@ class CommandOSSet : public Command u->isSuperAdmin = 1; notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_ON); Alog() << Config.s_OperServ << ": " << u->nick << " is a SuperAdmin"; - ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_SUPER_ADMIN_WALL_ON), u->nick.c_str()); + ircdproto->SendGlobops(OperServ, getstring(OPER_SUPER_ADMIN_WALL_ON), u->nick.c_str()); } else if (setting == "OFF") { u->isSuperAdmin = 0; notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_OFF); Alog() << Config.s_OperServ << ": " << u->nick << " is no longer a SuperAdmin"; - ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_SUPER_ADMIN_WALL_OFF), u->nick.c_str()); + ircdproto->SendGlobops(OperServ, getstring(OPER_SUPER_ADMIN_WALL_OFF), u->nick.c_str()); } else notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_SYNTAX); @@ -287,6 +287,11 @@ class CommandOSSet : public Command { syntax_error(Config.s_OperServ, u, "SET", OPER_SET_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SET); + } }; class OSSet : public Module @@ -298,13 +303,7 @@ class OSSet : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSSet()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SET); + this->AddCommand(OperServ, new CommandOSSet()); } }; diff --git a/src/core/os_sgline.c b/src/core/os_sgline.c deleted file mode 100644 index 4a4e5a13b..000000000 --- a/src/core/os_sgline.c +++ /dev/null @@ -1,410 +0,0 @@ -/* OperServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" -#include "hashcomp.h" - -int sgline_view_callback(SList *slist, int number, void *item, va_list args); -int sgline_list_callback(SList *slist, int number, void *item, va_list args); -int sgline_view(int number, SXLine *sx, User *u, int *sent_header); -int sgline_list(int number, SXLine *sx, User *u, int *sent_header); - -static int sxline_del_callback(SList *slist, void *item, va_list args) -{ - User *u = va_arg(args, User *); - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SGLINE)); - return 1; -} - -class CommandOSSGLine : public Command -{ - private: - CommandReturn OnAdd(User *u, const std::vector<ci::string> ¶ms) - { - int deleted = 0; - unsigned last_param = 2; - const char *param, *expiry; - char rest[BUFSIZE]; - time_t expires; - - param = params.size() > 1 ? params[1].c_str() : NULL; - if (param && *param == '+') - { - expiry = param; - param = params.size() > 2 ? params[2].c_str() : NULL; - last_param = 3; - } - else - expiry = NULL; - - expires = expiry ? dotime(expiry) : Config.SGLineExpiry; - /* If the expiry given does not contain a final letter, it's in days, - * said the doc. Ah well. - */ - if (expiry && isdigit(expiry[strlen(expiry) - 1])) - expires *= 86400; - /* Do not allow less than a minute expiry time */ - if (expires && expires < 60) - { - notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); - return MOD_CONT; - } - else if (expires > 0) - expires += time(NULL); - - if (!param) - { - this->OnSyntaxError(u, "ADD"); - return MOD_CONT; - } - snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : ""); - - if (std::string(rest).find(':') == std::string::npos) - { - this->OnSyntaxError(u, "ADD"); - return MOD_CONT; - } - - sepstream sep(rest, ':'); - std::string mask; - sep.GetToken(mask); - std::string reason = sep.GetRemaining(); - - if (!mask.empty() && !reason.empty()) { - /* Clean up the last character of the mask if it is a space - * See bug #761 - */ - unsigned masklen = mask.size(); - if (mask[masklen - 1] == ' ') - mask.erase(masklen - 1); - - const char *cmask = mask.c_str(); - - /* We first do some sanity check on the proposed mask. */ - - if (!mask.empty() && strspn(cmask, "*?") == strlen(cmask)) { - notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, cmask); - return MOD_CONT; - } - - deleted = add_sgline(u, cmask, u->nick.c_str(), expires, reason.c_str()); - if (deleted < 0) - return MOD_CONT; - else if (deleted) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, deleted); - notice_lang(Config.s_OperServ, u, OPER_SGLINE_ADDED, cmask); - - if (Config.WallOSSGLine) - { - char buf[128]; - - if (!expires) - strcpy(buf, "does not expire"); - else - { - int wall_expiry = expires - time(NULL); - const char *s = NULL; - - if (wall_expiry >= 86400) - { - wall_expiry /= 86400; - s = "day"; - } - else if (wall_expiry >= 3600) - { - wall_expiry /= 3600; - s = "hour"; - } - else if (wall_expiry >= 60) - { - wall_expiry /= 60; - s = "minute"; - } - - snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); - } - - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SGLINE for %s (%s)", u->nick.c_str(), cmask, buf); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - } - else - this->OnSyntaxError(u, "ADD"); - - return MOD_CONT; - } - - CommandReturn OnDel(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res = 0; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask) - { - this->OnSyntaxError(u, "DEL"); - return MOD_CONT; - } - - if (!sglines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY); - return MOD_CONT; - } - - if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) - { - /* Deleting a range */ - res = slist_delete_range(&sglines, mask, sxline_del_callback); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH); - return MOD_CONT; - } - else if (res == 1) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_ONE); - else - notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, res); - } - else { - if ((res = slist_indexof(&sglines, const_cast<char *>(mask))) == -1) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask); - return MOD_CONT; - } - - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sglines.list[res]), SX_SGLINE)); - slist_delete(&sglines, res); - notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED, mask); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - return MOD_CONT; - } - - CommandReturn OnList(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!sglines.count) { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&sglines, mask, &sgline_list_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < sglines.count; ++i) - { - amask = (static_cast<SXLine *>(sglines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - sgline_list(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH); - else - notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SGLine"); - } - - return MOD_CONT; - } - - CommandReturn OnView(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!sglines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&sglines, mask, &sgline_view_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < sglines.count; ++i) - { - amask = (static_cast<SXLine *>(sglines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - sgline_view(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH); - } - - return MOD_CONT; - } - - CommandReturn OnClear(User *u) - { - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SGLINE)); - slist_clear(&sglines, 1); - notice_lang(Config.s_OperServ, u, OPER_SGLINE_CLEAR); - - return MOD_CONT; - } - public: - CommandOSSGLine() : Command("SGLINE", 1, 3, "operserv/sgline") - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - ci::string cmd = params[0]; - - if (cmd == "ADD") - return this->OnAdd(u, params); - else if (cmd == "DEL") - return this->OnDel(u, params); - else if (cmd == "LIST") - return this->OnList(u, params); - else if (cmd == "VIEW") - return this->OnView(u, params); - else if (cmd == "CLEAR") - return this->OnClear(u); - else - this->OnSyntaxError(u, ""); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_OperServ, u, OPER_HELP_SGLINE); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX); - } -}; - -class OSSGLine : public Module -{ - public: - OSSGLine(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(OPERSERV, new CommandOSSGLine()); - - if (!ircd->sgline) - throw ModuleException("Your IRCd does not support SGLine"); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SGLINE); - } -}; - -/* Lists an SGLINE entry, prefixing it with the header if needed */ -int sgline_view(int number, SXLine *sx, User *u, int *sent_header) -{ - char timebuf[32], expirebuf[256]; - struct tm tm; - - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_HEADER); - *sent_header = 1; - } - - tm = *localtime(&sx->seton); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires); - notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason); - - return 1; -} - -/* Callback for enumeration purposes */ -int sgline_view_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return sgline_view(number, static_cast<SXLine *>(item), u, sent_header); -} - -/* Lists an SGLINE entry, prefixing it with the header if needed */ -int sgline_list(int number, SXLine *sx, User *u, int *sent_header) -{ - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_HEADER); - *sent_header = 1; - } - - notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_FORMAT, number, sx->mask, sx->reason); - - return 1; -} - -/* Callback for enumeration purposes */ -int sgline_list_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return sgline_list(number, static_cast<SXLine *>(item), u, sent_header); -} - -MODULE_INIT(OSSGLine) diff --git a/src/core/os_shutdown.c b/src/core/os_shutdown.cpp index be97153b4..772457602 100644 --- a/src/core/os_shutdown.c +++ b/src/core/os_shutdown.cpp @@ -41,6 +41,11 @@ class CommandOSShutdown : public Command notice_help(Config.s_OperServ, u, OPER_HELP_SHUTDOWN); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SHUTDOWN); + } }; class OSShutdown : public Module @@ -52,13 +57,7 @@ class OSShutdown : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSShutdown()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SHUTDOWN); + this->AddCommand(OperServ, new CommandOSShutdown()); } }; diff --git a/src/core/os_snline.cpp b/src/core/os_snline.cpp new file mode 100644 index 000000000..5463457de --- /dev/null +++ b/src/core/os_snline.cpp @@ -0,0 +1,425 @@ +/* OperServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" +#include "hashcomp.h" + +class SNLineDelCallback : public NumberList +{ + User *u; + unsigned Deleted; + public: + SNLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0) + { + } + + ~SNLineDelCallback() + { + if (!Deleted) + notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH); + else if (Deleted == 0) + notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_ONE); + else + notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_SEVERAL, Deleted); + } + + void HandleNumber(unsigned Number) + { + XLine *x = SNLine->GetEntry(Number - 1); + + if (!x) + return; + + ++Deleted; + DoDel(u, x); + } + + static void DoDel(User *u, XLine *x) + { + SNLine->DelXLine(x); + } +}; + +class SNLineListCallback : public NumberList +{ + protected: + User *u; + bool SentHeader; + public: + SNLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false) + { + } + + ~SNLineListCallback() + { + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH); + } + + virtual void HandleNumber(unsigned Number) + { + XLine *x = SNLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER); + } + + DoList(u, x, Number - 1); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str()); + } +}; + +class SNLineViewCallback : public SNLineListCallback +{ + public: + SNLineViewCallback(User *_u, const std::string &numlist) : SNLineListCallback(_u, numlist) + { + } + + void HandleNumber(unsigned Number) + { + XLine *x = SNLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER); + } + + DoList(u, x, Number - 1); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + char timebuf[32], expirebuf[256]; + struct tm tm; + + tm = *localtime(&x->Created); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires); + notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str()); + } +}; + +class CommandOSSNLine : public Command +{ + private: + CommandReturn OnAdd(User *u, const std::vector<ci::string> ¶ms) + { + unsigned last_param = 2; + const char *param, *expiry; + char rest[BUFSIZE]; + time_t expires; + + param = params.size() > 1 ? params[1].c_str() : NULL; + if (param && *param == '+') + { + expiry = param; + param = params.size() > 2 ? params[2].c_str() : NULL; + last_param = 3; + } + else + expiry = NULL; + + expires = expiry ? dotime(expiry) : Config.SNLineExpiry; + /* If the expiry given does not contain a final letter, it's in days, + * said the doc. Ah well. + */ + if (expiry && isdigit(expiry[strlen(expiry) - 1])) + expires *= 86400; + /* Do not allow less than a minute expiry time */ + if (expires && expires < 60) + { + notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); + return MOD_CONT; + } + else if (expires > 0) + expires += time(NULL); + + if (!param) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : ""); + + if (std::string(rest).find(':') == std::string::npos) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + + sepstream sep(rest, ':'); + ci::string mask; + sep.GetToken(mask); + std::string reason = sep.GetRemaining(); + + if (!mask.empty() && !reason.empty()) { + /* Clean up the last character of the mask if it is a space + * See bug #761 + */ + unsigned masklen = mask.size(); + if (mask[masklen - 1] == ' ') + mask.erase(masklen - 1); + + XLine *x = SNLine->Add(OperServ, u, mask, expires, reason); + + if (!x) + return MOD_CONT; + + notice_lang(Config.s_OperServ, u, OPER_SNLINE_ADDED, mask.c_str()); + + if (Config.WallOSSNLine) + { + char buf[128]; + + if (!expires) + strcpy(buf, "does not expire"); + else + { + int wall_expiry = expires - time(NULL); + const char *s = NULL; + + if (wall_expiry >= 86400) + { + wall_expiry /= 86400; + s = "day"; + } + else if (wall_expiry >= 3600) + { + wall_expiry /= 3600; + s = "hour"; + } + else if (wall_expiry >= 60) + { + wall_expiry /= 60; + s = "minute"; + } + + snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); + } + + ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SNLINE for %s (%s)", u->nick.c_str(), mask.c_str(), buf); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + } + else + this->OnSyntaxError(u, "ADD"); + + return MOD_CONT; + } + + CommandReturn OnDel(User *u, const std::vector<ci::string> ¶ms) + { + if (SNLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (mask.empty()) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SNLineDelCallback(u, mask.c_str()))->Process(); + else + { + XLine *x = SNLine->HasEntry(mask); + + if (!x) + { + notice_lang(Config.s_OperServ, u, OPER_SNLINE_NOT_FOUND, mask.c_str()); + return MOD_CONT; + } + + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SNLINE)); + + SNLineDelCallback::DoDel(u, x); + notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED, mask.c_str()); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + return MOD_CONT; + } + + CommandReturn OnList(User *u, const std::vector<ci::string> ¶ms) + { + if (SNLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SNLineListCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SNLine->GetCount(); ++i) + { + XLine *x = SNLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER); + } + + SNLineListCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH); + else + notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SNLine"); + } + + return MOD_CONT; + } + + CommandReturn OnView(User *u, const std::vector<ci::string> ¶ms) + { + if (SNLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SNLineViewCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SNLine->GetCount(); ++i) + { + XLine *x = SNLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER); + } + + SNLineViewCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH); + } + + return MOD_CONT; + } + + CommandReturn OnClear(User *u) + { + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SNLINE)); + SNLine->Clear(); + notice_lang(Config.s_OperServ, u, OPER_SNLINE_CLEAR); + + return MOD_CONT; + } + public: + CommandOSSNLine() : Command("SNLINE", 1, 3, "operserv/snline") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ci::string cmd = params[0]; + + if (cmd == "ADD") + return this->OnAdd(u, params); + else if (cmd == "DEL") + return this->OnDel(u, params); + else if (cmd == "LIST") + return this->OnList(u, params); + else if (cmd == "VIEW") + return this->OnView(u, params); + else if (cmd == "CLEAR") + return this->OnClear(u); + else + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_OperServ, u, OPER_HELP_SNLINE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_OperServ, u, "SNLINE", OPER_SNLINE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SNLINE); + } +}; + +class OSSNLine : public Module +{ + public: + OSSNLine(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + + this->AddCommand(OperServ, new CommandOSSNLine()); + + if (!ircd->snline) + throw ModuleException("Your IRCd does not support SNLine"); + } +}; + +MODULE_INIT(OSSNLine) diff --git a/src/core/os_sqline.c b/src/core/os_sqline.c deleted file mode 100644 index c48791620..000000000 --- a/src/core/os_sqline.c +++ /dev/null @@ -1,395 +0,0 @@ -/* OperServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -int sqline_view_callback(SList *slist, int number, void *item, va_list args); -int sqline_list_callback(SList *slist, int number, void *item, va_list args); -int sqline_view(int number, SXLine *sx, User *u, int *sent_header); -int sqline_list(int number, SXLine *sx, User *u, int *sent_header); - -static int sxline_del_callback(SList *slist, void *item, va_list args) -{ - User *u = va_arg(args, User *); - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SQLINE)); - return 1; -} - -class CommandOSSQLine : public Command -{ - private: - CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) - { - int deleted = 0; - unsigned last_param = 2; - const char *expiry, *mask; - char reason[BUFSIZE]; - time_t expires; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - if (mask && *mask == '+') - { - expiry = mask; - mask = params.size() > 2 ? params[2].c_str() : NULL; - last_param = 3; - } - else - expiry = NULL; - - expires = expiry ? dotime(expiry) : Config.SQLineExpiry; - /* If the expiry given does not contain a final letter, it's in days, - * said the doc. Ah well. - */ - if (expiry && isdigit(expiry[strlen(expiry) - 1])) - expires *= 86400; - /* Do not allow less than a minute expiry time */ - if (expires != 0 && expires < 60) - { - notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); - return MOD_CONT; - } - else if (expires > 0) - expires += time(NULL); - - if (params.size() <= last_param) - { - this->OnSyntaxError(u, "ADD"); - return MOD_CONT; - } - snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); - if (mask && *reason) - { - /* We first do some sanity check on the proposed mask. */ - if (strspn(mask, "*") == strlen(mask)) - { - notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask); - return MOD_CONT; - } - - /* Channel SQLINEs are only supported on Bahamut servers */ - if (*mask == '#' && !ircd->chansqline) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED); - return MOD_CONT; - } - - deleted = add_sqline(u, mask, u->nick.c_str(), expires, reason); - if (deleted < 0) - return MOD_CONT; - else if (deleted) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, deleted); - notice_lang(Config.s_OperServ, u, OPER_SQLINE_ADDED, mask); - - if (Config.WallOSSQLine) - { - char buf[128]; - - if (!expires) - strcpy(buf, "does not expire"); - else - { - int wall_expiry = expires - time(NULL); - const char *s = NULL; - - if (wall_expiry >= 86400) - { - wall_expiry /= 86400; - s = "day"; - } - else if (wall_expiry >= 3600) - { - wall_expiry /= 3600; - s = "hour"; - } - else if (wall_expiry >= 60) - { - wall_expiry /= 60; - s = "minute"; - } - - snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); - } - - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SQLINE for %s (%s)", u->nick.c_str(), mask, buf); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - } - else - this->OnSyntaxError(u, "ADD"); - - return MOD_CONT; - } - - CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res = 0; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask) - { - this->OnSyntaxError(u, "DEL"); - return MOD_CONT; - } - - if (!sqlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); - return MOD_CONT; - } - - if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) - { - /* Deleting a range */ - res = slist_delete_range(&sqlines, mask, sxline_del_callback); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); - return MOD_CONT; - } - else if (res == 1) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE); - else - notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, res); - } - else { - if ((res = slist_indexof(&sqlines, const_cast<char *>(mask))) == -1) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask); - return MOD_CONT; - } - - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sqlines.list[res]), SX_SQLINE)); - slist_delete(&sqlines, res); - notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - return MOD_CONT; - } - - CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!sqlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&sqlines, mask, &sqline_list_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < sqlines.count; ++i) - { - amask = (static_cast<SXLine *>(sqlines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - sqline_list(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); - else - notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SQLine"); - } - - return MOD_CONT; - } - - CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!sqlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&sqlines, mask, &sqline_view_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < sqlines.count; ++i) - { - amask = (static_cast<SXLine *>(sqlines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - sqline_view(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); - } - - return MOD_CONT; - } - - CommandReturn DoClear(User *u) - { - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SQLINE)); - slist_clear(&sqlines, 1); - notice_lang(Config.s_OperServ, u, OPER_SQLINE_CLEAR); - - return MOD_CONT; - } - public: - CommandOSSQLine() : Command("SQLINE", 1, 4, "operserv/sqline") - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - ci::string cmd = params[0]; - - if (cmd == "ADD") - return this->DoAdd(u, params); - else if (cmd == "DEL") - return this->DoDel(u, params); - else if (cmd == "LIST") - return this->DoList(u, params); - else if (cmd == "VIEW") - return this->DoView(u, params); - else if (cmd == "CLEAR") - return this->DoClear(u); - else - this->OnSyntaxError(u, ""); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_OperServ, u, OPER_HELP_SQLINE); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_OperServ, u, "SQLINE", OPER_SQLINE_SYNTAX); - } -}; - -class OSSQLine : public Module -{ - public: - OSSQLine(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(OPERSERV, new CommandOSSQLine()); - - if (!ircd->sqline) - throw ModuleException("Your IRCd does not support QLines."); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLINE); - } -}; - -int sqline_view(int number, SXLine *sx, User *u, int *sent_header) -{ - char timebuf[32], expirebuf[256]; - struct tm tm; - - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER); - *sent_header = 1; - } - - tm = *localtime(&sx->seton); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires); - notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason); - - return 1; -} - -/* Callback for enumeration purposes */ -int sqline_view_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return sqline_view(number, static_cast<SXLine *>(item), u, sent_header); -} - -/* Lists an SQLINE entry, prefixing it with the header if needed */ -int sqline_list(int number, SXLine *sx, User *u, int *sent_header) -{ - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER); - *sent_header = 1; - } - - notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, number, sx->mask, sx->reason); - - return 1; -} - -/* Callback for enumeration purposes */ -int sqline_list_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return sqline_list(number, static_cast<SXLine *>(item), u, sent_header); -} - -MODULE_INIT(OSSQLine) diff --git a/src/core/os_sqline.cpp b/src/core/os_sqline.cpp new file mode 100644 index 000000000..37f22b14a --- /dev/null +++ b/src/core/os_sqline.cpp @@ -0,0 +1,406 @@ +/* OperServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class SQLineDelCallback : public NumberList +{ + User *u; + unsigned Deleted; + public: + SQLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0) + { + } + + ~SQLineDelCallback() + { + if (!Deleted) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); + else if (Deleted == 0) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE); + else + notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, Deleted); + } + + void HandleNumber(unsigned Number) + { + XLine *x = SQLine->GetEntry(Number - 1); + + if (!x) + return; + + ++Deleted; + DoDel(u, x - 1); + } + + static void DoDel(User *u, XLine *x) + { + SQLine->DelXLine(x); + } +}; + +class SQLineListCallback : public NumberList +{ + protected: + User *u; + bool SentHeader; + public: + SQLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false) + { + } + + ~SQLineListCallback() + { + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); + } + + virtual void HandleNumber(unsigned Number) + { + XLine *x = SQLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER); + } + + DoList(u, x, Number - 1); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str()); + } +}; + +class SQLineViewCallback : public SQLineListCallback +{ + public: + SQLineViewCallback(User *_u, const std::string &numlist) : SQLineListCallback(_u, numlist) + { + } + + void HandleNumber(unsigned Number) + { + XLine *x = SQLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER); + } + + DoList(u, x, Number); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + char timebuf[32], expirebuf[256]; + struct tm tm; + + tm = *localtime(&x->Created); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires); + notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, +expirebuf, x->Reason.c_str()); + } +}; + + +class CommandOSSQLine : public Command +{ + private: + CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) + { + unsigned last_param = 2; + const char *expiry, *mask; + char reason[BUFSIZE]; + time_t expires; + + mask = params.size() > 1 ? params[1].c_str() : NULL; + if (mask && *mask == '+') + { + expiry = mask; + mask = params.size() > 2 ? params[2].c_str() : NULL; + last_param = 3; + } + else + expiry = NULL; + + expires = expiry ? dotime(expiry) : Config.SQLineExpiry; + /* If the expiry given does not contain a final letter, it's in days, + * said the doc. Ah well. + */ + if (expiry && isdigit(expiry[strlen(expiry) - 1])) + expires *= 86400; + /* Do not allow less than a minute expiry time */ + if (expires != 0 && expires < 60) + { + notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); + return MOD_CONT; + } + else if (expires > 0) + expires += time(NULL); + + if (params.size() <= last_param) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); + if (mask && *reason) + { + XLine *x = SQLine->Add(OperServ, u, mask, expires, reason); + + if (!x) + return MOD_CONT; + + notice_lang(Config.s_OperServ, u, OPER_SQLINE_ADDED, mask); + + if (Config.WallOSSQLine) + { + char buf[128]; + + if (!expires) + strcpy(buf, "does not expire"); + else + { + int wall_expiry = expires - time(NULL); + const char *s = NULL; + + if (wall_expiry >= 86400) + { + wall_expiry /= 86400; + s = "day"; + } + else if (wall_expiry >= 3600) + { + wall_expiry /= 3600; + s = "hour"; + } + else if (wall_expiry >= 60) + { + wall_expiry /= 60; + s = "minute"; + } + + snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); + } + + ircdproto->SendGlobops(OperServ, "%s added an SQLINE for %s (%s)", u->nick.c_str(), mask, buf); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + } + else + this->OnSyntaxError(u, "ADD"); + + return MOD_CONT; + } + + CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) + { + if (SQLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (mask.empty()) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SQLineDelCallback(u, mask.c_str()))->Process(); + else + { + XLine *x = SQLine->HasEntry(mask); + + if (!x) + { + notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask.c_str()); + return MOD_CONT; + } + + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SQLINE)); + + SQLineDelCallback::DoDel(u, x); + notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask.c_str()); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + return MOD_CONT; + } + + CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) + { + if (SQLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SQLineListCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SQLine->GetCount(); ++i) + { + XLine *x = SQLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER); + } + + SQLineListCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); + else + notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SQLine"); + } + + return MOD_CONT; + } + + CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) + { + if (SQLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SQLineViewCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SQLine->GetCount(); ++i) + { + XLine *x = SQLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER); + } + + SQLineViewCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH); + } + + return MOD_CONT; + } + + CommandReturn DoClear(User *u) + { + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SQLINE)); + SGLine->Clear(); + notice_lang(Config.s_OperServ, u, OPER_SQLINE_CLEAR); + + return MOD_CONT; + } + public: + CommandOSSQLine() : Command("SQLINE", 1, 4, "operserv/sqline") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ci::string cmd = params[0]; + + if (cmd == "ADD") + return this->DoAdd(u, params); + else if (cmd == "DEL") + return this->DoDel(u, params); + else if (cmd == "LIST") + return this->DoList(u, params); + else if (cmd == "VIEW") + return this->DoView(u, params); + else if (cmd == "CLEAR") + return this->DoClear(u); + else + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_OperServ, u, OPER_HELP_SQLINE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_OperServ, u, "SQLINE", OPER_SQLINE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLINE); + } +}; + +class OSSQLine : public Module +{ + public: + OSSQLine(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + this->AddCommand(OperServ, new CommandOSSQLine()); + + if (!ircd->sqline) + throw ModuleException("Your IRCd does not support QLines."); + } +}; + +MODULE_INIT(OSSQLine) diff --git a/src/core/os_staff.c b/src/core/os_staff.cpp index f0e831bfc..930f8db7b 100644 --- a/src/core/os_staff.c +++ b/src/core/os_staff.cpp @@ -34,8 +34,10 @@ class CommandOSStaff : public Command if (na) { /* We have to loop all users as some may be logged into an account but not a nick */ - for (User *u2 = firstuser(); u2; u2 = nextuser()) + for (user_map::iterator uit = UserListByNick.begin(); uit != UserListByNick.end(); ++uit) { + User *u2 = uit->second; + if (u2->Account() && u2->Account() == na->nc) { found = 1; @@ -61,6 +63,11 @@ class CommandOSStaff : public Command notice_help(Config.s_OperServ, u, OPER_HELP_STAFF); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STAFF); + } }; class OSStaff : public Module @@ -72,13 +79,7 @@ class OSStaff : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSStaff()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STAFF); + this->AddCommand(OperServ, new CommandOSStaff()); } }; diff --git a/src/core/os_stats.c b/src/core/os_stats.cpp index 711e1f646..5b993ad8f 100644 --- a/src/core/os_stats.c +++ b/src/core/os_stats.cpp @@ -21,16 +21,19 @@ void get_operserv_stats(long *nrec, long *memuse); * @param s The server to start counting from * @return Amount of servers connected to server s **/ -int stats_count_servers(Server *s) +static int stats_count_servers(Server *s) { - int count = 0; + if (!s) + return 0; + + int count = 1; - while (s) + if (s->GetLinks()) { - ++count; - if (s->links) - count += stats_count_servers(s->links); - s = s->next; + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + count += stats_count_servers(*it); + } } return count; @@ -43,7 +46,7 @@ class CommandOSStats : public Command { int timeout; /* AKILLs */ - notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, akills.count); + notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, SGLine->GetCount()); timeout = Config.AutokillExpiry + 59; if (timeout >= 172800) notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_DAYS, timeout / 86400); @@ -59,30 +62,30 @@ class CommandOSStats : public Command notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_MIN); else notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_NONE); - if (ircd->sgline) + if (ircd->snline) { - /* SGLINEs */ - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_COUNT, sglines.count); - timeout = Config.SGLineExpiry + 59; + /* SNLINEs */ + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_COUNT, SNLine->GetCount()); + timeout = Config.SNLineExpiry + 59; if (timeout >= 172800) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAYS, timeout / 86400); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAYS, timeout / 86400); else if (timeout >= 86400) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAY); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAY); else if (timeout >= 7200) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOURS, timeout / 3600); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOURS, timeout / 3600); else if (timeout >= 3600) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOUR); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOUR); else if (timeout >= 120) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MINS, timeout / 60); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MINS, timeout / 60); else if (timeout >= 60) - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MIN); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MIN); else - notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_NONE); + notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_NONE); } if (ircd->sqline) { /* SQLINEs */ - notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, sqlines.count); + notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, SQLine->GetCount()); timeout = Config.SQLineExpiry + 59; if (timeout >= 172800) notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_EXPIRE_DAYS, timeout / 86400); @@ -102,7 +105,7 @@ class CommandOSStats : public Command if (ircd->szline) { /* SZLINEs */ - notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, szlines.count); + notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, SZLine->GetCount()); timeout = Config.SZLineExpiry + 59; if (timeout >= 172800) notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_EXPIRE_DAYS, timeout / 86400); @@ -214,9 +217,9 @@ class CommandOSStats : public Command if (!buf.empty()) buf.erase(buf.begin()); - notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, serv_uplink->name); + notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, Me->GetUplink()->GetName().c_str()); notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_CAPAB, buf.c_str()); - notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(serv_uplink)); + notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(Me->GetUplink())); return MOD_CONT; } @@ -290,6 +293,11 @@ class CommandOSStats : public Command notice_help(Config.s_OperServ, u, OPER_HELP_STATS); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STATS); + } }; class OSStats : public Module @@ -301,76 +309,80 @@ class OSStats : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSStats()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STATS); + this->AddCommand(OperServ, new CommandOSStats()); } }; void get_operserv_stats(long *nrec, long *memuse) { - int i; + unsigned i; long mem = 0, count = 0, mem2 = 0, count2 = 0; - Akill *ak; - SXLine *sx; + XLine *x; - count += akills.count; - mem += akills.capacity; - mem += akills.count * sizeof(Akill); + count += SGLine->GetCount(); + mem += SGLine->GetCount() * sizeof(XLine); - for (i = 0; i < akills.count; ++i) + for (i = 0; i < SGLine->GetCount(); ++i) { - ak = static_cast<Akill *>(akills.list[i]); - mem += strlen(ak->user) + 1; - mem += strlen(ak->host) + 1; - mem += strlen(ak->by) + 1; - mem += strlen(ak->reason) + 1; + x = SGLine->GetEntry(i); + + mem += x->GetNick().length() + 1; + mem += x->GetUser().length() + 1; + mem += x->GetHost().length() + 1; + mem += x->Mask.length() + 1; + mem += x->By.length() + 1; + mem += x->Reason.length() + 1; } - if (ircd->sgline) + if (ircd->snline) { - count += sglines.count; - mem += sglines.capacity; - mem += sglines.count * sizeof(SXLine); + count += SNLine->GetCount(); + mem += SNLine->GetCount() * sizeof(XLine); - for (i = 0; i < sglines.count; ++i) + for (i = 0; i < SNLine->GetCount(); ++i) { - sx = static_cast<SXLine *>(sglines.list[i]); - mem += strlen(sx->mask) + 1; - mem += strlen(sx->by) + 1; - mem += strlen(sx->reason) + 1; + x = SNLine->GetEntry(i); + + mem += x->GetNick().length() + 1; + mem += x->GetUser().length() + 1; + mem += x->GetHost().length() + 1; + mem += x->Mask.length() + 1; + mem += x->By.length() + 1; + mem += x->Reason.length() + 1; } } if (ircd->sqline) { - count += sqlines.count; - mem += sqlines.capacity; - mem += sqlines.count * sizeof(SXLine); + count += SQLine->GetCount(); + mem += SGLine->GetCount() * sizeof(XLine); - for (i = 0; i < sqlines.count; ++i) + for (i = 0; i < SQLine->GetCount(); ++i) { - sx = static_cast<SXLine *>(sqlines.list[i]); - mem += strlen(sx->mask) + 1; - mem += strlen(sx->by) + 1; - mem += strlen(sx->reason) + 1; + x = SNLine->GetEntry(i); + + mem += x->GetNick().length() + 1; + mem += x->GetUser().length() + 1; + mem += x->GetHost().length() + 1; + mem += x->Mask.length() + 1; + mem += x->By.length() + 1; + mem += x->Reason.length() + 1; } } if (ircd->szline) { - count += szlines.count; - mem += szlines.capacity; - mem += szlines.count * sizeof(SXLine); - - for (i = 0; i < szlines.count; ++i) + count += SZLine->GetCount(); + mem += SZLine->GetCount() * sizeof(XLine); + + for (i = 0; i < SZLine->GetCount(); ++i) { - sx = static_cast<SXLine *>(szlines.list[i]); - mem += strlen(sx->mask) + 1; - mem += strlen(sx->by) + 1; - mem += strlen(sx->reason) + 1; + x = SZLine->GetEntry(i); + + mem += x->GetNick().length() + 1; + mem += x->GetUser().length() + 1; + mem += x->GetHost().length() + 1; + mem += x->Mask.length() + 1; + mem += x->By.length() + 1; + mem += x->Reason.length() + 1; } } diff --git a/src/core/os_svsnick.c b/src/core/os_svsnick.cpp index 856f460bc..d3b0a5eaa 100644 --- a/src/core/os_svsnick.c +++ b/src/core/os_svsnick.cpp @@ -54,14 +54,14 @@ class CommandOSSVSNick : public Command /* Check for a nick in use or a forbidden/suspended nick */ if (!(u2 = finduser(nick))) notice_lang(Config.s_OperServ, u, NICK_X_NOT_IN_USE, nick); - else if (finduser(newnick.c_str())) + else if (finduser(newnick)) notice_lang(Config.s_OperServ, u, NICK_X_IN_USE, newnick.c_str()); - else if ((na = findnick(newnick.c_str())) && (na->HasFlag(NS_FORBIDDEN))) + else if ((na = findnick(newnick)) && (na->HasFlag(NS_FORBIDDEN))) notice_lang(Config.s_OperServ, u, NICK_X_FORBIDDEN, newnick.c_str()); else { notice_lang(Config.s_OperServ, u, OPER_SVSNICK_NEWNICK, nick, newnick.c_str()); - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick, newnick.c_str()); + ircdproto->SendGlobops(OperServ, "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick, newnick.c_str()); ircdproto->SendForceNickChange(u2, newnick.c_str(), time(NULL)); } return MOD_CONT; @@ -77,6 +77,11 @@ class CommandOSSVSNick : public Command { syntax_error(Config.s_OperServ, u, "SVSNICK", OPER_SVSNICK_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SVSNICK); + } }; class OSSVSNick : public Module @@ -88,16 +93,10 @@ class OSSVSNick : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSSVSNick()); + this->AddCommand(OperServ, new CommandOSSVSNick()); if (!ircd->svsnick) throw ModuleException("Your IRCd does not support SVSNICK"); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SVSNICK); } }; diff --git a/src/core/os_szline.c b/src/core/os_szline.c deleted file mode 100644 index b99844835..000000000 --- a/src/core/os_szline.c +++ /dev/null @@ -1,394 +0,0 @@ -/* OperServ core functions - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -/*************************************************************************/ - -#include "module.h" - -int szline_view_callback(SList *slist, int number, void *item, va_list args); -int szline_list_callback(SList *slist, int number, void *item, va_list args); -int szline_view(int number, SXLine *sx, User *u, int *sent_header); -int szline_list(int number, SXLine *sx, User *u, int *sent_header); - -static int sxline_del_callback(SList *slist, void *item, va_list args) -{ - User *u = va_arg(args, User *); - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SZLINE)); - return 1; -} - -class CommandOSSZLine : public Command -{ - private: - CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) - { - int deleted = 0; - unsigned last_param = 2; - const char *expiry, *mask; - char reason[BUFSIZE]; - time_t expires; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - if (mask && *mask == '+') - { - expiry = mask; - mask = params.size() > 2 ? params[2].c_str() : NULL; - last_param = 3; - } - else - expiry = NULL; - - expires = expiry ? dotime(expiry) : Config.SZLineExpiry; - /* If the expiry given does not contain a final letter, it's in days, - * said the doc. Ah well. - */ - if (expiry && isdigit(expiry[strlen(expiry) - 1])) - expires *= 86400; - /* Do not allow less than a minute expiry time */ - if (expires != 0 && expires < 60) - { - notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); - return MOD_CONT; - } - else if (expires > 0) - expires += time(NULL); - - if (params.size() <= last_param) - { - this->OnSyntaxError(u, "ADD"); - return MOD_CONT; - } - snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); - if (mask && *reason) - { - /* We first do some sanity check on the proposed mask. */ - - if (strchr(mask, '!') || strchr(mask, '@')) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS); - return MOD_CONT; - } - - if (strspn(mask, "*?") == strlen(mask)) - { - notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask); - return MOD_CONT; - } - - deleted = add_szline(u, mask, u->nick.c_str(), expires, reason); - if (deleted < 0) - return MOD_CONT; - else if (deleted) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, deleted); - notice_lang(Config.s_OperServ, u, OPER_SZLINE_ADDED, mask); - - if (Config.WallOSSZLine) - { - char buf[128]; - - if (!expires) - strcpy(buf, "does not expire"); - else - { - int wall_expiry = expires - time(NULL); - const char *s = NULL; - - if (wall_expiry >= 86400) - { - wall_expiry /= 86400; - s = "day"; - } - else if (wall_expiry >= 3600) - { - wall_expiry /= 3600; - s = "hour"; - } - else if (wall_expiry >= 60) - { - wall_expiry /= 60; - s = "minute"; - } - - snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); - } - - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SZLINE for %s (%s)", u->nick.c_str(), mask, buf); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - } - else - this->OnSyntaxError(u, "ADD"); - - return MOD_CONT; - } - - CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res = 0; - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask) - { - this->OnSyntaxError(u, "DEL"); - return MOD_CONT; - } - - if (!szlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); - return MOD_CONT; - } - - if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) - { - /* Deleting a range */ - res = slist_delete_range(&szlines, mask, sxline_del_callback); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); - return MOD_CONT; - } - else if (res == 1) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE); - else - notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, res); - } - else - { - if ((res = slist_indexof(&szlines, const_cast<char *>(mask))) == -1) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask); - return MOD_CONT; - } - - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(szlines.list[res]), SX_SZLINE)); - slist_delete(&szlines, res); - notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask); - } - - if (readonly) - notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); - - return MOD_CONT; - } - - CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!szlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&szlines, mask, &szline_list_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < szlines.count; ++i) - { - amask = (static_cast<SXLine *>(szlines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - szline_list(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); - } - - return MOD_CONT; - } - - CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) - { - const char *mask; - int res, sent_header = 0; - - if (!szlines.count) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); - return MOD_CONT; - } - - mask = params.size() > 1 ? params[1].c_str() : NULL; - - if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))) - { - res = slist_enum(&szlines, mask, &szline_view_callback, u, &sent_header); - if (!res) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); - return MOD_CONT; - } - } - else - { - int i; - char *amask; - - for (i = 0; i < szlines.count; ++i) - { - amask = (static_cast<SXLine *>(szlines.list[i]))->mask; - if (!stricmp(mask, amask) || Anope::Match(amask, mask, false)) - szline_view(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header); - } - - if (!sent_header) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); - } - - return MOD_CONT; - } - - CommandReturn DoClear(User *u) - { - FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SZLINE)); - slist_clear(&szlines, 1); - notice_lang(Config.s_OperServ, u, OPER_SZLINE_CLEAR); - - return MOD_CONT; - } - public: - CommandOSSZLine() : Command("SZLINE", 1, 4, "operserv/szline") - { - } - - CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) - { - ci::string cmd = params[0]; - - if (cmd == "ADD") - return this->DoAdd(u, params); - else if (cmd == "DEL") - return this->DoDel(u, params); - else if (cmd == "LIST") - return this->DoList(u, params); - else if (cmd == "VIEW") - return this->DoView(u, params); - else if (cmd == "CLEAR") - return this->DoClear(u); - else - this->OnSyntaxError(u, ""); - return MOD_CONT; - } - - bool OnHelp(User *u, const ci::string &subcommand) - { - notice_help(Config.s_OperServ, u, OPER_HELP_SZLINE); - return true; - } - - void OnSyntaxError(User *u, const ci::string &subcommand) - { - syntax_error(Config.s_OperServ, u, "SZLINE", OPER_SZLINE_SYNTAX); - } -}; - -class OSSZLine : public Module -{ - public: - OSSZLine(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - this->SetAuthor("Anope"); - this->SetVersion(VERSION_STRING); - this->SetType(CORE); - - this->AddCommand(OPERSERV, new CommandOSSZLine()); - - if (!ircd->szline) - throw ModuleException("Your IRCd does not support ZLINEs"); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SZLINE); - } -}; - -int szline_view(int number, SXLine *sx, User *u, int *sent_header) -{ - char timebuf[32], expirebuf[256]; - struct tm tm; - - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER); - *sent_header = 1; - } - - tm = *localtime(&sx->seton); - strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); - expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires); - notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason); - - return 1; -} - -/* Callback for enumeration purposes */ -int szline_view_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return szline_view(number, static_cast<SXLine *>(item), u, sent_header); -} - -/* Callback for enumeration purposes */ -int szline_list_callback(SList *slist, int number, void *item, va_list args) -{ - User *u = va_arg(args, User *); - int *sent_header = va_arg(args, int *); - - return szline_list(number, static_cast<SXLine *>(item), u, sent_header); -} - -/* Lists an SZLINE entry, prefixing it with the header if needed */ -int szline_list(int number, SXLine *sx, User *u, int *sent_header) -{ - if (!sx) - return 0; - - if (!*sent_header) - { - notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER); - *sent_header = 1; - } - - notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, number, sx->mask, sx->reason); - - return 1; -} - -MODULE_INIT(OSSZLine) diff --git a/src/core/os_szline.cpp b/src/core/os_szline.cpp new file mode 100644 index 000000000..2a8b642cd --- /dev/null +++ b/src/core/os_szline.cpp @@ -0,0 +1,404 @@ +/* OperServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +/*************************************************************************/ + +#include "module.h" + +class SZLineDelCallback : public NumberList +{ + User *u; + unsigned Deleted; + public: + SZLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0) + { + } + + ~SZLineDelCallback() + { + if (!Deleted) + notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); + else if (Deleted == 0) + notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE); + else + notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, Deleted); + } + + void HandleNumber(unsigned Number) + { + XLine *x = SZLine->GetEntry(Number - 1); + + if (!x) + return; + + ++Deleted; + DoDel(u, x); + } + + static void DoDel(User *u, XLine *x) + { + SZLine->DelXLine(x); + } +}; + +class SZLineListCallback : public NumberList +{ + protected: + User *u; + bool SentHeader; + public: + SZLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false) + { + } + + ~SZLineListCallback() + { + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); + } + + virtual void HandleNumber(unsigned Number) + { + XLine *x = SZLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER); + } + + DoList(u, x, Number - 1); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str()); + } +}; + +class SZLineViewCallback : public SZLineListCallback +{ + public: + SZLineViewCallback(User *_u, const std::string &numlist) : SZLineListCallback(_u, numlist) + { + } + + void HandleNumber(unsigned Number) + { + XLine *x = SZLine->GetEntry(Number - 1); + + if (!x) + return; + + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER); + } + + DoList(u, x, Number - 1); + } + + static void DoList(User *u, XLine *x, unsigned Number) + { + char timebuf[32], expirebuf[256]; + struct tm tm; + + tm = *localtime(&x->Created); + strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm); + expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires); + notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, +expirebuf, x->Reason.c_str()); + } +}; + + +class CommandOSSZLine : public Command +{ + private: + CommandReturn DoAdd(User *u, const std::vector<ci::string> ¶ms) + { + unsigned last_param = 2; + const char *expiry, *mask; + char reason[BUFSIZE]; + time_t expires; + + mask = params.size() > 1 ? params[1].c_str() : NULL; + if (mask && *mask == '+') + { + expiry = mask; + mask = params.size() > 2 ? params[2].c_str() : NULL; + last_param = 3; + } + else + expiry = NULL; + + expires = expiry ? dotime(expiry) : Config.SZLineExpiry; + /* If the expiry given does not contain a final letter, it's in days, + * said the doc. Ah well. + */ + if (expiry && isdigit(expiry[strlen(expiry) - 1])) + expires *= 86400; + /* Do not allow less than a minute expiry time */ + if (expires != 0 && expires < 60) + { + notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME); + return MOD_CONT; + } + else if (expires > 0) + expires += time(NULL); + + if (params.size() <= last_param) + { + this->OnSyntaxError(u, "ADD"); + return MOD_CONT; + } + snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : ""); + if (mask && *reason) + { + XLine *x = SZLine->Add(OperServ, u, mask, expires, reason); + + if (!x) + return MOD_CONT; + + notice_lang(Config.s_OperServ, u, OPER_SZLINE_ADDED, mask); + + if (Config.WallOSSZLine) + { + char buf[128]; + + if (!expires) + strcpy(buf, "does not expire"); + else + { + int wall_expiry = expires - time(NULL); + const char *s = NULL; + + if (wall_expiry >= 86400) + { + wall_expiry /= 86400; + s = "day"; + } + else if (wall_expiry >= 3600) + { + wall_expiry /= 3600; + s = "hour"; + } + else if (wall_expiry >= 60) + { + wall_expiry /= 60; + s = "minute"; + } + + snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s"); + } + + ircdproto->SendGlobops(OperServ, "%s added an SZLINE for %s (%s)", u->nick.c_str(), mask, buf); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + } + else + this->OnSyntaxError(u, "ADD"); + + return MOD_CONT; + } + + CommandReturn DoDel(User *u, const std::vector<ci::string> ¶ms) + { + if (SZLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1].c_str() : ""; + + if (mask.empty()) + { + this->OnSyntaxError(u, "DEL"); + return MOD_CONT; + } + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SZLineDelCallback(u, mask.c_str()))->Process(); + else + { + XLine *x = SZLine->HasEntry(mask); + + if (!x) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask.c_str()); + return MOD_CONT; + } + + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SZLINE)); + + SZLineDelCallback::DoDel(u, x); + notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask.c_str()); + } + + if (readonly) + notice_lang(Config.s_OperServ, u, READ_ONLY_MODE); + + return MOD_CONT; + } + + CommandReturn DoList(User *u, const std::vector<ci::string> ¶ms) + { + if (SZLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SZLineListCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SZLine->GetCount(); ++i) + { + XLine *x = SZLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER); + } + + SZLineListCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); + } + + return MOD_CONT; + } + + CommandReturn DoView(User *u, const std::vector<ci::string> ¶ms) + { + if (SZLine->GetList().empty()) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY); + return MOD_CONT; + } + + const ci::string mask = params.size() > 1 ? params[1] : ""; + + if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length()) + (new SZLineViewCallback(u, mask.c_str()))->Process(); + else + { + bool SentHeader = false; + + for (unsigned i = 0; i < SZLine->GetCount(); ++i) + { + XLine *x = SZLine->GetEntry(i); + + if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask))) + { + if (!SentHeader) + { + SentHeader = true; + notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER); + } + + SZLineViewCallback::DoList(u, x, i); + } + } + + if (!SentHeader) + notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH); + } + + return MOD_CONT; + } + + CommandReturn DoClear(User *u) + { + FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SZLINE)); + SZLine->Clear(); + notice_lang(Config.s_OperServ, u, OPER_SZLINE_CLEAR); + + return MOD_CONT; + } + public: + CommandOSSZLine() : Command("SZLINE", 1, 4, "operserv/szline") + { + } + + CommandReturn Execute(User *u, const std::vector<ci::string> ¶ms) + { + ci::string cmd = params[0]; + + if (cmd == "ADD") + return this->DoAdd(u, params); + else if (cmd == "DEL") + return this->DoDel(u, params); + else if (cmd == "LIST") + return this->DoList(u, params); + else if (cmd == "VIEW") + return this->DoView(u, params); + else if (cmd == "CLEAR") + return this->DoClear(u); + else + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + bool OnHelp(User *u, const ci::string &subcommand) + { + notice_help(Config.s_OperServ, u, OPER_HELP_SZLINE); + return true; + } + + void OnSyntaxError(User *u, const ci::string &subcommand) + { + syntax_error(Config.s_OperServ, u, "SZLINE", OPER_SZLINE_SYNTAX); + } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SZLINE); + } +}; + +class OSSZLine : public Module +{ + public: + OSSZLine(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion(VERSION_STRING); + this->SetType(CORE); + + this->AddCommand(OperServ, new CommandOSSZLine()); + + if (!ircd->szline) + throw ModuleException("Your IRCd does not support ZLINEs"); + } +}; + +MODULE_INIT(OSSZLine) diff --git a/src/core/os_umode.c b/src/core/os_umode.cpp index 4911aded3..bfd0e3777 100644 --- a/src/core/os_umode.c +++ b/src/core/os_umode.cpp @@ -41,13 +41,13 @@ class CommandOSUMode : public Command notice_lang(Config.s_OperServ, u, NICK_X_NOT_IN_USE, nick); else { - u2->SetModes(findbot(Config.s_OperServ), modes); + u2->SetModes(OperServ, modes); notice_lang(Config.s_OperServ, u, OPER_UMODE_SUCCESS, nick); notice_lang(Config.s_OperServ, u2, OPER_UMODE_CHANGED, u->nick.c_str()); if (Config.WallOSMode) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used UMODE on %s", u->nick.c_str(), nick); + ircdproto->SendGlobops(OperServ, "\2%s\2 used UMODE on %s", u->nick.c_str(), nick); } return MOD_CONT; } @@ -62,6 +62,11 @@ class CommandOSUMode : public Command { syntax_error(Config.s_OperServ, u, "UMODE", OPER_UMODE_SYNTAX); } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UMODE); + } }; class OSUMode : public Module @@ -73,16 +78,10 @@ class OSUMode : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSUMode()); + this->AddCommand(OperServ, new CommandOSUMode()); if (!ircd->umode) throw ModuleException("Your IRCd does not support setting umodes"); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UMODE); } }; diff --git a/src/core/os_update.c b/src/core/os_update.cpp index 32ec6d804..0355db90e 100644 --- a/src/core/os_update.c +++ b/src/core/os_update.cpp @@ -33,6 +33,11 @@ class CommandOSUpdate : public Command notice_help(Config.s_OperServ, u, OPER_HELP_UPDATE); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UPDATE); + } }; class OSUpdate : public Module @@ -44,13 +49,7 @@ class OSUpdate : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSUpdate()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UPDATE); + this->AddCommand(OperServ, new CommandOSUpdate()); } }; diff --git a/src/core/os_userlist.c b/src/core/os_userlist.cpp index 93caa7a60..2a35299fd 100644 --- a/src/core/os_userlist.c +++ b/src/core/os_userlist.cpp @@ -55,32 +55,28 @@ class CommandOSUserList : public Command } else { - char mask[BUFSIZE]; - int i; - User *u2; - notice_lang(Config.s_OperServ, u, OPER_USERLIST_HEADER); - for (i = 0; i < 1024; ++i) + for (user_map::const_iterator uit = UserListByNick.begin(); uit != UserListByNick.end(); ++uit) { - for (u2 = userlist[i]; u2; u2 = u2->next) + User *u2 = uit->second; + + if (pattern) { - if (pattern) + char mask[BUFSIZE]; + snprintf(mask, sizeof(mask), "%s!%s@%s", u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); + if (!Anope::Match(mask, pattern, false)) + continue; + if (!Modes.empty()) { - snprintf(mask, sizeof(mask), "%s!%s@%s", u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); - if (!Anope::Match(mask, pattern, false)) - continue; - if (!Modes.empty()) + for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) { - for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it) - { - if (!u2->HasMode(*it)) - continue; - } + if (!u2->HasMode(*it)) + continue; } } - notice_lang(Config.s_OperServ, u, OPER_USERLIST_RECORD, u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); } + notice_lang(Config.s_OperServ, u, OPER_USERLIST_RECORD, u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str()); } } @@ -93,6 +89,11 @@ class CommandOSUserList : public Command notice_help(Config.s_OperServ, u, OPER_HELP_USERLIST); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_USERLIST); + } }; class OSUserList : public Module @@ -104,13 +105,7 @@ class OSUserList : public Module this->SetVersion(VERSION_STRING); this->SetType(CORE); - this->AddCommand(OPERSERV, new CommandOSUserList()); - - ModuleManager::Attach(I_OnOperServHelp, this); - } - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_USERLIST); + this->AddCommand(OperServ, new CommandOSUserList()); } }; diff --git a/src/core/ss_main.c b/src/core/ss_main.cpp index 271f6f87e..d0578b16d 100644 --- a/src/core/ss_main.c +++ b/src/core/ss_main.cpp @@ -14,7 +14,6 @@ #include "module.h" BotInfo *statserv = NULL; -CommandHash *cmdTable[MAX_CMD_HASH]; class CommandSSHelp : public Command { @@ -40,8 +39,6 @@ class SSMain : public Module this->SetType(CORE); this->SetPermanent(true); - this->AddCommand(cmdTable, new CommandSSHelp()); - statserv = findbot("StatServ"); if (!statserv) { @@ -49,23 +46,19 @@ class SSMain : public Module statserv = new BotInfo("StatServ", Config.ServiceUser, Config.ServiceHost, "Stats Service"); } Alog() << "Done creating SS"; - statserv->cmdTable = cmdTable; + + this->AddCommand(statserv, new CommandSSHelp()); } ~SSMain() { - CommandHash *current; - Command *c; - for (int i = 0; i < MAX_CMD_HASH; ++i) + if (statserv) { - for (current = cmdTable[i]; current; current = current->next) + for (std::map<ci::string, Command *>::iterator it = statserv->Commands.begin(); it != statserv->Commands.end(); ++it) { - for (c = current->c; c; c = c->next) - this->DelCommand(cmdTable, c->name.c_str()); + this->DelCommand(statserv, it->second); } - } - if (statserv) - { + ircdproto->SendQuit(statserv, "Quit due to module unload."); delete statserv; } diff --git a/src/encrypt.c b/src/encrypt.cpp index 4f76ee895..4f76ee895 100644 --- a/src/encrypt.c +++ b/src/encrypt.cpp diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 65e546c9c..462064235 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -164,3 +164,46 @@ bool sepstream::StreamEnd() { return n == tokens.end(); } + +/** Return a hash value for a string + * @param s The string + * @return The hash value + */ +size_t hash_compare_std_string::operator()(const std::string &s) const +{ + register size_t t = 0; + + for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) + t = 5 * t + static_cast<const unsigned char>(*it); + + return t; +} + +/** Return a hash value for a string using case insensitivity + * @param s The string + * @return The hash value + */ +size_t hash_compare_ci_string::operator()(const ci::string &s) const +{ + register size_t t = 0; + + for (ci::string::const_iterator it = s.begin(); it != s.end(); ++it) + t = 5 * t + ascii_case_insensitive_map[static_cast<const unsigned char>(*it)]; + + return t; +} + +/** Return a hash value for a string using RFC1459 case sensitivity rules + * @param s The string + * @return The hash value + */ +size_t hash_compare_irc_string::operator()(const irc::string &s) const +{ + register size_t t = 0; + + for (irc::string::const_iterator it = s.begin(); it != s.end(); ++it) + t = 5 * t + rfc_case_insensitive_map[static_cast<const unsigned char>(*it)]; + + return t; +} + diff --git a/src/hostserv.c b/src/hostserv.cpp index b34b272a3..8cce7783f 100644 --- a/src/hostserv.c +++ b/src/hostserv.cpp @@ -11,11 +11,9 @@ * */ -/*************************************************************************/ #include "services.h" -#include "pseudo.h" - -#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31)) +#include "modules.h" +#include "language.h" E int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask, char *creator, time_t time); @@ -40,21 +38,20 @@ void get_hostserv_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - for (int i = 0; i < 1024; ++i) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (NickAlias *na = nalists[i]; na; na = na->next) - { - if (!na->hostinfo.HasVhost()) - continue; - - if (!na->hostinfo.GetIdent().empty()) - mem += na->hostinfo.GetIdent().size(); - if (!na->hostinfo.GetHost().empty()) - mem += na->hostinfo.GetHost().size(); - if (!na->hostinfo.GetCreator().empty()) - mem += na->hostinfo.GetCreator().size(); - ++count; - } + NickAlias *na = it->second; + + if (!na->hostinfo.HasVhost()) + continue; + + if (!na->hostinfo.GetIdent().empty()) + mem += na->hostinfo.GetIdent().size(); + if (!na->hostinfo.GetHost().empty()) + mem += na->hostinfo.GetHost().size(); + if (!na->hostinfo.GetCreator().empty()) + mem += na->hostinfo.GetCreator().size(); + ++count; } *nrec = count; @@ -82,25 +79,25 @@ void hostserv_init() * @param buf Buffer holding the message * @return void */ -void hostserv(User * u, char *buf) +void hostserv(User *u, const std::string &buf) { - const char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) { + if (!u || buf.empty()) return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - s = ""; - } - ircdproto->SendCTCP(findbot(Config.s_HostServ), u->nick.c_str(), "PING %s", s); - } else { - if (ircd->vhost) { - mod_run_cmd(Config.s_HostServ, u, HOSTSERV, cmd); - } else { - notice_lang(Config.s_HostServ, u, SERVICE_OFFLINE, Config.s_HostServ); - } + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(HostServ, u->nick.c_str(), "%s", command.c_str()); + } + else if (!ircd->vhost) + { + notice_lang(Config.s_HostServ, u, SERVICE_OFFLINE, Config.s_HostServ); + } + else + { + mod_run_cmd(HostServ, u, buf); } } @@ -180,9 +177,9 @@ void HostServSyncVhosts(NickAlias *na) if (!na || !na->hostinfo.HasVhost()) return; - for (int i = 0; i < na->nc->aliases.count; i++) + for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it) { - NickAlias *nick = static_cast<NickAlias *>(na->nc->aliases.list[i]); + NickAlias *nick = *it; nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator()); } } diff --git a/src/init.c b/src/init.cpp index 5fc1a8ab2..5bc9f01d1 100644 --- a/src/init.c +++ b/src/init.cpp @@ -12,7 +12,8 @@ */ #include "services.h" -#include "pseudo.h" +#include "modules.h" + Uplink *uplink_server; extern void moduleAddMsgs(); @@ -32,20 +33,18 @@ void introduce_user(const std::string &user) lasttimes[LTSIZE - 1] = time(NULL); #undef LTSIZE /* We make the bots go online */ - BotInfo *bi; - int i; /* XXX: it might be nice to have this inside BotInfo's constructor, or something? */ - for (i = 0; i < 256; ++i) + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) { - for (bi = botlists[i]; bi; bi = bi->next) + BotInfo *bi = it->second; + + ci::string ci_bi_nick(bi->nick.c_str()); + if (user.empty() || ci_bi_nick == user) { - ci::string ci_bi_nick(bi->nick.c_str()); - if (user.empty() || ci_bi_nick == user) - { - ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid); - ircdproto->SendSQLine(bi->nick, "Reserved for services"); - } + ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid); + XLine x(bi->nick.c_str(), "Reserved for services"); + ircdproto->SendSQLine(&x); } } } @@ -197,13 +196,13 @@ int init_primary(int ac, char **av) if (GetCommandLineArgument("version", 'v')) { - Alog(LOG_TERMINAL) << "Anope-" << version_number << version_flags << " -- " << version_build; + Alog(LOG_TERMINAL) << "Anope-" << version_number << " -- " << version_build; return -1; } if (GetCommandLineArgument("help", 'h')) { - Alog(LOG_TERMINAL) << "Anope-" << version_number << version_flags << " -- " << version_build; + Alog(LOG_TERMINAL) << "Anope-" << version_number << " -- " << version_build; Alog(LOG_TERMINAL) << "Anope IRC Services (http://www.anope.org)"; Alog(LOG_TERMINAL) << "Usage ./" << SERVICES_BIN << " [options] ..."; Alog(LOG_TERMINAL) << "-c, --config=filename.conf"; @@ -326,9 +325,35 @@ int init_primary(int ac, char **av) } /* Add IRCD Protocol Module; exit if there are errors */ - if (protocol_module_init()) { + if (protocol_module_init()) return -1; - } + + /* First thing, add our core bots internally. Before modules are loaded and before the database is read + * This is used for modules adding commands and for the BotInfo* poiners in the command classes. + * When these bots are loaded from the databases the proper user/host/rname are added. + * + * If a user renames a bot in the configuration file, the new bot gets created here, and the old bot + * that is in the database gets created aswell, on its old nick. The old nick remains in all the channels + * etc and the new bot becomes the new client to accept commands. The user can use /bs bot del later + * if they want the old bot deleted. + * + * Note that it is important this is after loading the protocol module. The ircd struct must exist for + * the ts6_ functions + */ + if (Config.s_OperServ) + new BotInfo(Config.s_OperServ, Config.ServiceUser, Config.ServiceHost, Config.desc_OperServ); + if (Config.s_NickServ) + new BotInfo(Config.s_NickServ, Config.ServiceUser, Config.ServiceHost, Config.desc_NickServ); + if (Config.s_ChanServ) + new BotInfo(Config.s_ChanServ, Config.ServiceUser, Config.ServiceHost, Config.desc_ChanServ); + if (Config.s_HostServ) + new BotInfo(Config.s_HostServ, Config.ServiceUser, Config.ServiceHost, Config.desc_HostServ); + if (Config.s_MemoServ) + new BotInfo(Config.s_MemoServ, Config.ServiceUser, Config.ServiceHost, Config.desc_MemoServ); + if (Config.s_BotServ) + new BotInfo(Config.s_BotServ, Config.ServiceUser, Config.ServiceHost, Config.desc_BotServ); + if (Config.s_GlobalNoticer) + new BotInfo(Config.s_GlobalNoticer, Config.ServiceUser, Config.ServiceHost, Config.desc_GlobalNoticer); /* Add Encryption Modules */ ModuleManager::LoadModuleList(Config.EncModuleList); @@ -439,49 +464,6 @@ int init_secondary(int ac, char **av) FOREACH_RESULT(I_OnLoadDatabase, OnLoadDatabase()); Alog() << "Databases loaded"; - /* this is only used on the first run of Anope. */ - if (!nbots) - { - if (Config.s_OperServ) - new BotInfo(Config.s_OperServ, Config.ServiceUser, Config.ServiceHost, Config.desc_OperServ); - if (Config.s_NickServ) - new BotInfo(Config.s_NickServ, Config.ServiceUser, Config.ServiceHost, Config.desc_NickServ); - if (Config.s_ChanServ) - new BotInfo(Config.s_ChanServ, Config.ServiceUser, Config.ServiceHost, Config.desc_ChanServ); - if (Config.s_HostServ) - new BotInfo(Config.s_HostServ, Config.ServiceUser, Config.ServiceHost, Config.desc_HostServ); - if (Config.s_MemoServ) - new BotInfo(Config.s_MemoServ, Config.ServiceUser, Config.ServiceHost, Config.desc_MemoServ); - if (Config.s_BotServ) - new BotInfo(Config.s_BotServ, Config.ServiceUser, Config.ServiceHost, Config.desc_BotServ); - if (Config.s_GlobalNoticer) - new BotInfo(Config.s_GlobalNoticer, Config.ServiceUser, Config.ServiceHost, Config.desc_GlobalNoticer); - } - else - { - /* If a botname was changed in the config, reflect it */ - for (int i = 0; i < 256; ++i) - { - for (BotInfo *bi = botlists[i]; bi; bi = bi->next) - { - if (bi->HasFlag(BI_OPERSERV) && bi->nick != Config.s_OperServ) - bi->ChangeNick(Config.s_OperServ); - else if (bi->HasFlag(BI_NICKSERV) && bi->nick != Config.s_NickServ) - bi->ChangeNick(Config.s_NickServ); - else if (bi->HasFlag(BI_CHANSERV) && bi->nick != Config.s_ChanServ) - bi->ChangeNick(Config.s_ChanServ); - else if (bi->HasFlag(BI_HOSTSERV) && bi->nick != Config.s_HostServ) - bi->ChangeNick(Config.s_HostServ); - else if (bi->HasFlag(BI_MEMOSERV) && bi->nick != Config.s_MemoServ) - bi->ChangeNick(Config.s_MemoServ); - else if (bi->HasFlag(BI_BOTSERV) && bi->nick != Config.s_BotServ) - bi->ChangeNick(Config.s_BotServ); - else if (bi->HasFlag(BI_GLOBAL) && bi->nick != Config.s_GlobalNoticer) - bi->ChangeNick(Config.s_GlobalNoticer); - } - } - } - FOREACH_MOD(I_OnPostLoadDatabases, OnPostLoadDatabases()); return 0; diff --git a/src/ircd.c b/src/ircd.cpp index 70d961d81..70d961d81 100644 --- a/src/ircd.c +++ b/src/ircd.cpp diff --git a/src/language.c b/src/language.cpp index 3f5c900e9..3f5c900e9 100644 --- a/src/language.c +++ b/src/language.cpp diff --git a/src/log.c b/src/log.cpp index 0ed07a371..bf5fd10fb 100644 --- a/src/log.c +++ b/src/log.cpp @@ -12,7 +12,6 @@ */ #include "services.h" -#include "pseudo.h" static FILE *logfile; @@ -276,7 +275,7 @@ Alog::~Alog() else if (Level == LOG_TERMINAL) // XXX dont use this yet unless you know we're at terminal and not daemonized std::cout << buf.str() << std::endl; if (Config.LogChannel && LogChan && !debug && findchan(Config.LogChannel)) { - ircdproto->SendPrivmsg(findbot(Config.s_GlobalNoticer), Config.LogChannel, "%s", buf.str().c_str()); + ircdproto->SendPrivmsg(Global, Config.LogChannel, "%s", buf.str().c_str()); } errno = errno_save; } diff --git a/src/mail.c b/src/mail.c deleted file mode 100644 index ef3d6cd4d..000000000 --- a/src/mail.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Mail utility routines. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "language.h" - -/*************************************************************************/ - -/** - * Begins to send a mail. Must be followed by a MailEnd call. - * Returns NULL if the call failed. Error messages are - * automatically sent to the user. - * @param u the User struct - * @param nr NickReqest Struct - * @param subject Subject of the email - * @param service Service to respond with - * @return MailInfo struct - */ -MailInfo *MailRegBegin(User * u, NickRequest * nr, char *subject, - char *service) -{ - int timeToWait = 0; - if (!u || !nr || !subject || !service) { - return NULL; - } - - if (!Config.UseMail) { - notice_lang(service, u, MAIL_DISABLED); - } else if ((time(NULL) - u->lastmail < Config.MailDelay)) { - timeToWait = Config.MailDelay - (time(NULL) - u->lastmail); - notice_lang(service, u, MAIL_DELAYED, timeToWait); - } else if (!nr->email) { - notice_lang(service, u, MAIL_INVALID, nr->nick); - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = u; - mail->recipient = NULL; - mail->recip = nr; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - notice_lang(service, u, MAIL_LATER); - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nr->nick, nr->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nr->nick, nr->email); - } - fprintf(mail->pipe, "Subject: %s\n", subject); - return mail; - } - - return NULL; -} - -/*************************************************************************/ - -/** - * Begins to send a mail. Must be followed by a MailEnd call. - * Returns NULL if the call failed. Error messages are - * automatically sent to the user. - * @param u the User struct - * @param nc NickCore Struct - * @param subject Subject of the email - * @param service Service to respond with - * @return MailInfo struct - */ -MailInfo *MailBegin(User * u, NickCore * nc, char *subject, char *service) -{ - if (!u || !nc || !subject || !service) { - return NULL; - } - - if (!Config.UseMail) { - notice_lang(service, u, MAIL_DISABLED); - } else if (((time(NULL) - u->lastmail < Config.MailDelay) - || (time(NULL) - nc->lastmail < Config.MailDelay)) - && !(u->Account() && u->Account()->IsServicesOper())) { - notice_lang(service, u, MAIL_DELAYED, Config.MailDelay); - } else if (!nc->email) { - notice_lang(service, u, MAIL_INVALID, nc->display); - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = u; - mail->recipient = nc; - mail->recip = NULL; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - notice_lang(service, u, MAIL_LATER); - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display, - nc->email); - } - fprintf(mail->pipe, "Subject: %s\n", subject); - - return mail; - } - - return NULL; -} - -/*************************************************************************/ - -/** - * new function to send memo mails - * @param nc NickCore Struct - * @return MailInfo struct - */ -MailInfo *MailMemoBegin(NickCore * nc) -{ - - if (!nc) - return NULL; - - if (!Config.UseMail || !nc->email) { - return NULL; - - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = NULL; - mail->recipient = nc; - mail->recip = NULL; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display, - nc->email); - } - fprintf(mail->pipe, "Subject: %s\n", - getstring(MEMO_MAIL_SUBJECT)); - return mail; - } -} - -/*************************************************************************/ - -/** - * Finish to send the mail. Cleanup everything. - * @param mail MailInfo Struct - * @return void - */ -void MailEnd(MailInfo * mail) -{ - /* - param checking modified because we don't - have an user sending this mail. - Certus, 02.04.2004 */ - - if (!mail || !mail->pipe) { /* removed sender check */ - return; - } - - if (!mail->recipient && !mail->recip) { - return; - } - - pclose(mail->pipe); - - if (mail->sender) /* added sender check */ - mail->sender->lastmail = time(NULL); - - if (mail->recipient) - mail->recipient->lastmail = time(NULL); - else - mail->recip->lastmail = time(NULL); - - - delete mail; -} - -/*************************************************************************/ - -/** - * Resets the MailDelay protection. - * @param u the User struct - * @param nc NickCore Struct - * @return void - */ -void MailReset(User * u, NickCore * nc) -{ - if (u) - u->lastmail = 0; - if (nc) - nc->lastmail = 0; -} - -/*************************************************************************/ - -/** - * Checks whether we have a valid, common e-mail address. - * This is NOT entirely RFC compliant, and won't be so, because I said - * *common* cases. ;) It is very unlikely that e-mail addresses that - * are really being used will fail the check. - * - * FIXME: rewrite this a bit cleaner. - * @param email Email to Validate - * @return int - */ -int MailValidate(const char *email) -{ - int has_period = 0, len; - char copy[BUFSIZE], *domain; - - static char specials[] = - { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', - ' ' - }; - - if (!email) - return 0; - strlcpy(copy, email, sizeof(copy)); - - domain = strchr(copy, '@'); - if (!domain) - return 0; - *domain = '\0'; - domain++; - - /* Don't accept NULL copy or domain. */ - if (*copy == 0 || *domain == 0) - return 0; - - /* Check for forbidden characters in the name */ - for (unsigned int i = 0; i < strlen(copy); i++) { - - if (copy[i] <= 31 || copy[i] >= 127) - return 0; - for (unsigned int j = 0; j < 13; j++) - if (copy[i] == specials[j]) - return 0; - } - - /* Check for forbidden characters in the domain, and if it seems to be valid. */ - for (int i = 0; i < (len = strlen(domain)); i++) { - if (domain[i] <= 31 || domain[i] >= 127) - return 0; - for (unsigned int j = 0; j < 13; j++) - if (domain[i] == specials[j]) - return 0; - if (domain[i] == '.') { - if (i == 0 || i == len - 1) - return 0; - has_period = 1; - } - } - - if (!has_period) - return 0; - - return 1; -} diff --git a/src/mail.cpp b/src/mail.cpp new file mode 100644 index 000000000..9e1c60c6b --- /dev/null +++ b/src/mail.cpp @@ -0,0 +1,151 @@ +#include "services.h" +#include "language.h" + +MailThread::~MailThread() +{ + if (Success) + Alog() << "Successfully delivered mail for " << MailTo << " (" << Addr << ")"; + else + Alog() << "Error delivering mail for " << MailTo << " (" << Addr << ")"; +} + +void MailThread::Run() +{ + FILE *pipe = popen(Config.SendMailPath, "w"); + + if (!pipe) + { + return; + } + + fprintf(pipe, "From: %s\n", Config.SendFrom); + if (Config.DontQuoteAddresses) + fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str()); + else + fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str()); + fprintf(pipe, "Subject: %s\n", Subject.c_str()); + fprintf(pipe, "%s", Message.c_str()); + fprintf(pipe, "\n.\n"); + + pclose(pipe); + + Success = true; +} + +bool Mail(User *u, NickRequest *nr, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nr || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nr->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nr->nick); + else + { + u->lastmail = nr->lastmail = t; + threadEngine.Start(new MailThread(nr->nick, nr->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(User *u, NickCore *nc, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nc || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nc->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nc->display); + else + { + u->lastmail = nc->lastmail = t; + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(NickCore *nc, const std::string &subject, const std::string &message) +{ + if (!Config.UseMail || !nc || !nc->email || subject.empty() || message.empty()) + return false; + + nc->lastmail = time(NULL); + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + + return true; +} + +/** + * Checks whether we have a valid, common e-mail address. + * This is NOT entirely RFC compliant, and won't be so, because I said + * *common* cases. ;) It is very unlikely that e-mail addresses that + * are really being used will fail the check. + * + * @param email Email to Validate + * @return bool + */ +bool MailValidate(const std::string &email) +{ + bool has_period = false; + char copy[BUFSIZE]; + + static char specials[] = { + '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' ' + }; + + if (email.empty()) + return false; + strlcpy(copy, email.c_str(), sizeof(copy)); + + char *domain = strchr(copy, '@'); + if (!domain) + return false; + *domain++ = '\0'; + + /* Don't accept NULL copy or domain. */ + if (!*copy || !*domain) + return false; + + /* Check for forbidden characters in the name */ + for (unsigned int i = 0; i < strlen(copy); i++) + { + if (copy[i] <= 31 || copy[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (copy[i] == specials[j]) + return false; + } + + /* Check for forbidden characters in the domain */ + for (unsigned int i = 0; i < strlen(domain); i++) + { + if (domain[i] <= 31 || domain[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (domain[i] == specials[j]) + return false; + if (domain[i] == '.') + { + if (i == 0 || i == strlen(domain) - 1) + return false; + has_period = true; + } + } + + return has_period; +} + diff --git a/src/main.c b/src/main.cpp index d17d98a39..70c7f9e7e 100644 --- a/src/main.c +++ b/src/main.cpp @@ -43,7 +43,7 @@ std::string services_dir; /* -dir dirname */ std::string services_bin; /* Binary as specified by the user */ std::string orig_cwd; /* Original current working directory */ -std::string log_filename = LOG_FILENAME; /* -log filename */ +std::string log_filename = "services.log"; /* -log filename */ int debug = 0; /* -debug */ int readonly = 0; /* -readonly */ bool LogChan = false; /* -logchan */ @@ -83,7 +83,6 @@ const char version_number_dotted[] = VERSION_STRING_DOTTED; const char version_build[] = "build #" BUILD ", compiled " __DATE__ " " __TIME__; /* the space is needed cause if you build with nothing it will complain */ -const char version_flags[] = " " VER_OS; /******** Local variables! ********/ @@ -156,16 +155,6 @@ extern void expire_all() expire_nicks(); expire_chans(); expire_requests(); - expire_akills(); - if (ircd->sgline) { - expire_sglines(); - } - if (ircd->sqline) { - expire_sqlines(); - } - if (ircd->szline) { - expire_szlines(); - } expire_exceptions(); FOREACH_MOD(I_OnDatabaseExpire, OnDatabaseExpire()); @@ -198,14 +187,20 @@ void do_restart_services() if (!quitmsg) quitmsg = "Restarting"; + /* Send a quit for all of our bots */ + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + /* Don't use quitmsg here, it may contain information you don't want people to see */ + ircdproto->SendQuit(it->second, "Restarting"); + } ircdproto->SendSquit(Config.ServerName, quitmsg); /* Process to send the last bits of information before disconnecting */ socketEngine.Process(); delete UplinkSock; close_log(); /* First don't unload protocol module, then do so */ - modules_unload_all(false); - modules_unload_all(true); + ModuleManager::UnloadAll(false); + ModuleManager::UnloadAll(true); chdir(binary_dir.c_str()); execve(services_bin.c_str(), my_av, my_envp); if (!readonly) { @@ -225,8 +220,6 @@ void do_restart_services() static void services_shutdown() { - User *u, *next; - FOREACH_MOD(I_OnPreShutdown, OnPreShutdown()); if (!quitmsg) @@ -234,14 +227,18 @@ static void services_shutdown() Alog() << quitmsg; if (started && UplinkSock) { + /* Send a quit for all of our bots */ + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + /* Don't use quitmsg here, it may contain information you don't want people to see */ + ircdproto->SendQuit(it->second, "Shutting down"); + } + ircdproto->SendSquit(Config.ServerName, quitmsg); - if (uplink) - delete [] uplink; - u = firstuser(); - while (u) { - next = nextuser(); - delete u; - u = next; + + while (!UserListByNick.empty()) + { + delete UserListByNick.begin()->second; } } /* Process to send the last bits of information before disconnecting */ @@ -249,8 +246,8 @@ static void services_shutdown() delete UplinkSock; FOREACH_MOD(I_OnShutdown, OnShutdown()); /* First don't unload protocol module, then do so */ - modules_unload_all(false); - modules_unload_all(true); + ModuleManager::UnloadAll(false); + ModuleManager::UnloadAll(true); /* just in case they weren't all removed at least run once */ ModuleRunTimeDirCleanUp(); } @@ -392,12 +389,20 @@ std::string GetFullProgDir(char *argv0) static bool Connect() { /* Connect to the remote server */ - std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(), end_uplink = Config.Uplinks.end(); int servernum = 1; - for (; curr_uplink != end_uplink; ++curr_uplink, ++servernum) + for (std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(); curr_uplink != Config.Uplinks.end(); ++curr_uplink, ++servernum) { uplink_server = *curr_uplink; + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreServerConnect, OnPreServerConnect(*curr_uplink, servernum)); + if (MOD_RESULT != EVENT_CONTINUE) + { + if (MOD_RESULT == EVENT_STOP) + break; + return true; + } + try { new UplinkSocket(uplink_server->host, uplink_server->port, Config.LocalHost ? Config.LocalHost : "", uplink_server->ipv6); @@ -412,6 +417,8 @@ static bool Connect() return true; } + uplink_server = NULL; + return false; } @@ -474,8 +481,6 @@ int main(int ac, char **av, char **envp) if ((i = init_secondary(ac, av)) != 0) return i; - FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect()); - /* If the first connect fails give up, don't sit endlessly trying to reconnect */ if (!Connect()) fatal_perror("Can't connect to any servers"); diff --git a/src/memory.c b/src/memory.cpp index 4343bf5e6..4343bf5e6 100644 --- a/src/memory.c +++ b/src/memory.cpp diff --git a/src/memoserv.c b/src/memoserv.cpp index 5236345f9..505b4ed18 100644 --- a/src/memoserv.c +++ b/src/memoserv.cpp @@ -12,14 +12,14 @@ */ #include "services.h" -#include "pseudo.h" +#include "modules.h" +#include "language.h" /*************************************************************************/ /* *INDENT-OFF* */ E void moduleAddMemoServCmds(); -static void new_memo_mail(NickCore *nc, Memo *m); -E void rsend_notify(User *u, Memo *m, const char *chan); +static bool SendMemoMail(NickCore *nc, Memo *m); /*************************************************************************/ @@ -51,20 +51,21 @@ void ms_init() * @param buf Buffer containing the privmsg * @return void */ -void memoserv(User * u, char *buf) +void memoserv(User *u, const std::string &buf) { - const char *cmd, *s; - - cmd = strtok(buf, " "); - if (!cmd) { + if (!u || buf.empty()) return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - s = ""; - } - ircdproto->SendCTCP(findbot(Config.s_MemoServ), u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(Config.s_MemoServ, u, MEMOSERV, cmd); + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(MemoServ, u->nick.c_str(), "%s", command.c_str()); + } + else + { + mod_run_cmd(MemoServ, u, buf); } } @@ -272,7 +273,6 @@ void memo_send(User * u, const char *name, const char *text, int z) if (z == 0 || z == 3) notice_lang(Config.s_MemoServ, u, MEMO_SENT, name); if (!ischan) { - NickAlias *na; NickCore *nc = (findnick(name))->nc; FOREACH_MOD(I_OnMemoSend, OnMemoSend(u, nc, m)); @@ -280,10 +280,10 @@ void memo_send(User * u, const char *name, const char *text, int z) if (Config.MSNotifyAll) { if ((nc->HasFlag(NI_MEMO_RECEIVE)) && get_ignore(name) == NULL) { - int i; - for (i = 0; i < nc->aliases.count; i++) { - na = static_cast<NickAlias *>(nc->aliases.list[i]); + for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it) + { + NickAlias *na = *it; User *user = finduser(na->nick); if (user && user->IsIdentified()) notice_lang(Config.s_MemoServ, user, @@ -300,7 +300,7 @@ void memo_send(User * u, const char *name, const char *text, int z) /* if (MSNotifyAll) */ /* let's get out the mail if set in the nickcore - certus */ if (nc->HasFlag(NI_MEMO_MAIL)) - new_memo_mail(nc, m); + SendMemoMail(nc, m); } else { Channel *c; @@ -356,32 +356,17 @@ int delmemo(MemoInfo * mi, int num) /*************************************************************************/ -static void new_memo_mail(NickCore * nc, Memo * m) +static bool SendMemoMail(NickCore *nc, Memo *m) { - MailInfo *mail = NULL; + char message[BUFSIZE]; - if (!nc || !m) - return; + snprintf(message, sizeof(message), getstring(NICK_MAIL_TEXT), nc->display, m->sender.c_str(), m->number, m->text); - mail = MailMemoBegin(nc); - if (!mail) { - return; - } - fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT1), nc->display); - fprintf(mail->pipe, "\n"); - fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT2), m->sender.c_str(), - m->number); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(MEMO_MAIL_TEXT3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", m->text); - fprintf(mail->pipe, "\n"); - MailEnd(mail); - return; + return Mail(nc, getstring(MEMO_MAIL_SUBJECT), message); } - /*************************************************************************/ + /* Send receipt notification to sender. */ void rsend_notify(User * u, Memo * m, const char *chan) diff --git a/src/messages.c b/src/messages.cpp index 5bac88650..81c64b1fb 100644 --- a/src/messages.c +++ b/src/messages.cpp @@ -12,7 +12,7 @@ */ #include "services.h" -#include "messages.h" +#include "modules.h" #include "language.h" /*************************************************************************/ @@ -101,44 +101,51 @@ int m_motd(const char *source) /*************************************************************************/ -int m_privmsg(const char *source, const std::string &receiver, const char *msg) +int m_privmsg(const std::string &source, const std::string &receiver, const std::string &message) { char *target; time_t starttime, stoptime; /* When processing started and finished */ - BotInfo *bi; - ChannelInfo *ci; - User *u; - - if (!source || !*source || receiver.empty() || !msg) { + if (source.empty() || receiver.empty() || message.empty()) + { return MOD_CONT; } - u = finduser(source); + User *u = finduser(source); + + if (!u) + { + Alog() << message << ": user record for " << source << " not found"; - if (!u) { - Alog() << msg << ": user record for " << source << " not found"; - /* Two lookups naughty, however, this won't happen often. -- w00t */ - if (findbot(receiver)) + BotInfo *bi = findbot(receiver); + if (bi) { - ircdproto->SendMessage(findbot(receiver), source, "%s", getstring(USER_RECORD_NOT_FOUND)); + ircdproto->SendMessage(bi, source.c_str(), "%s", getstring(USER_RECORD_NOT_FOUND)); } + return MOD_CONT; } - if (receiver[0] == '#') { - if (Config.s_BotServ && (ci = cs_findchan(receiver))) { + if (receiver[0] == '#' && Config.s_BotServ) + { + ChannelInfo *ci = cs_findchan(receiver); + if (ci) + { /* Some paranoia checks */ - if (!ci->HasFlag(CI_FORBIDDEN) && ci->c && ci->bi) { - botchanmsgs(u, ci, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX + if (!ci->HasFlag(CI_FORBIDDEN) && ci->c && ci->bi) + { + botchanmsgs(u, ci, message); } } - } else { + } + else + { /* Check if we should ignore. Operators always get through. */ - if (allow_ignore && !is_oper(u)) { - IgnoreData *ign = get_ignore(source); - if (ign) { - target = myStrGetToken(msg, ' ', 0); + if (allow_ignore && !is_oper(u)) + { + if (get_ignore(source.c_str())) + { + target = myStrGetToken(message.c_str(), ' ', 0); Alog() << "Ignored message from " << source << " to " << receiver << " using command " << target; delete [] target; return MOD_CONT; @@ -156,16 +163,18 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg) if (servername != Config.ServerName) return MOD_CONT; } - else if (Config.UseStrictPrivMsg) { + else if (Config.UseStrictPrivMsg) + { Alog(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source; notice_lang(receiver, u, INVALID_TARGET, receiver.c_str(), receiver.c_str(), Config.ServerName, receiver.c_str()); return MOD_CONT; } - starttime = time(NULL); + if (allow_ignore) + starttime = time(NULL); - bi = findbot(botname); + BotInfo *bi = findbot(botname); if (bi) { @@ -176,40 +185,37 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg) { notice_lang(Config.s_OperServ, u, ACCESS_DENIED); if (Config.WallBadOS) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "Denied access to %s from %s!%s@%s (non-oper)", Config.s_OperServ, u->nick.c_str(), u->GetIdent().c_str(), u->host); + ircdproto->SendGlobops(OperServ, "Denied access to %s from %s!%s@%s (non-oper)", Config.s_OperServ, u->nick.c_str(), u->GetIdent().c_str(), u->host); } else - operserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX + operserv(u, message); } else if (ci_bi_nick == Config.s_NickServ) - nickserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX - else if (ci_bi_nick== Config.s_ChanServ) + nickserv(u, message); + else if (ci_bi_nick == Config.s_ChanServ) { if (!is_oper(u) && Config.CSOpersOnly) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else - chanserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX + chanserv(u, message); } else if (ci_bi_nick == Config.s_MemoServ) - memoserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX + memoserv(u, message); else if (Config.s_HostServ && ci_bi_nick == Config.s_HostServ) - hostserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX + hostserv(u, message); else if (Config.s_BotServ) - { - if (ci_bi_nick == Config.s_BotServ) - botserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX - else - botmsgs(u, bi, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX - } + botserv(u, bi, message); } /* Add to ignore list if the command took a significant amount of time. */ - if (allow_ignore) { + if (allow_ignore) + { stoptime = time(NULL); - if (stoptime > starttime && *source && !strchr(source, '.')) - add_ignore(source, stoptime - starttime); + if (stoptime > starttime && source.find('.') == std::string::npos) + add_ignore(source.c_str(), stoptime - starttime); } } + return MOD_CONT; } @@ -218,7 +224,6 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg) int m_stats(const char *source, int ac, const char **av) { User *u; - NickCore *nc; if (ac < 1) return MOD_CONT; @@ -248,7 +253,8 @@ int m_stats(const char *source, int ac, const char **av) { std::string nick = it->first, type = it->second; - if ((nc = findcore(nick.c_str()))) + NickCore *nc = findcore(nick); + if (nc) ircdproto->SendNumeric(Config.ServerName, 243, source, "O * * %s %s 0", nick.c_str(), type.c_str()); } @@ -277,8 +283,8 @@ int m_stats(const char *source, int ac, const char **av) int m_version(const char *source, int ac, const char **av) { - if (source) ircdproto->SendNumeric(Config.ServerName, 351, source, "Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, - Config.EncModuleList.begin()->c_str(), version_build); + if (source) + ircdproto->SendNumeric(Config.ServerName, 351, source, "Anope-%s %s :%s -(%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build); return MOD_CONT; } @@ -318,20 +324,10 @@ int m_whois(const char *source, const char *who) } /* *INDENT-OFF* */ -void moduleAddMsgs() { - Message *m; - m = createMessage("STATS", m_stats); addCoreMessage(IRCD,m); - m = createMessage("TIME", m_time); addCoreMessage(IRCD,m); - m = createMessage("VERSION", m_version); addCoreMessage(IRCD,m); -} - -/*************************************************************************/ - -Message *find_message(const char *name) +void moduleAddMsgs() { - Message *m; - m = findMessage(IRCD, name); - return m; + Anope::AddMessage("STATS", m_stats); + Anope::AddMessage("TIME", m_time); + Anope::AddMessage("VERSION", m_version); } -/*************************************************************************/ diff --git a/src/misc.c b/src/misc.cpp index 338737007..51ff5e97c 100644 --- a/src/misc.c +++ b/src/misc.cpp @@ -27,6 +27,21 @@ struct arc4_stream { /*************************************************************************/ +/** Check if a file exists + * @param filename The file + * @return true if the file exists, false if it doens't + */ +bool IsFile(const std::string &filename) +{ + struct stat fileinfo; + if (!stat(filename.c_str(), &fileinfo)) + { + return true; + } + + return false; +} + /** * toupper: Like the ANSI functions, but make sure we return an * int instead of a (signed) char. @@ -208,83 +223,92 @@ const char *merge_args(int argc, char **argv) } /*************************************************************************/ -/** - * Process a string containing a number/range list in the form - * "n1[-n2][,n3[-n4]]...", calling a caller-specified routine for each - * number in the list. If the callback returns -1, stop immediately. - * Returns the sum of all nonnegative return values from the callback. - * If `count' is non-NULL, it will be set to the total number of times the - * callback was called. - * - * The callback should be of type range_callback_t, which is defined as: - * int (*range_callback_t)(User *u, int num, va_list args) - * @param numstr - * @param count_ret - * @param callback Call back function - * @param u User Struct - * @param ... various args - * @return int - */ -int process_numlist(const char *numstr, int *count_ret, - range_callback_t callback, User * u, ...) -{ - int n1, n2, i; - int res = 0, retval = 0, count = 0; - va_list args, preserve; - if (!numstr || !*numstr) { - return -1; - } +NumberList::NumberList(const std::string &list, bool descending) : desc(descending) +{ + char *error; + commasepstream sep(list); + std::string token; - va_start(args, u); - - /* - * This algorithm ignores invalid characters, ignores a dash - * when it precedes a comma, and ignores everything from the - * end of a valid number or range to the next comma or null. - */ - for (;;) { - n1 = n2 = strtol(numstr, const_cast<char **>(&numstr), 10); - numstr += strcspn(numstr, "0123456789,-"); - if (*numstr == '-') { - numstr++; - numstr += strcspn(numstr, "0123456789,"); - if (isdigit(*numstr)) { - n2 = strtol(numstr, const_cast<char **>(&numstr), 10); - numstr += strcspn(numstr, "0123456789,-"); + sep.GetToken(token); + if (token.empty()) + token = list; + do + { + size_t t = token.find('-'); + + if (t == std::string::npos) + { + unsigned num = strtol(token.c_str(), &error, 10); + if (*error == '\0') + { + numbers.insert(num); } - } - for (i = n1; i <= n2 && i >= 0; i++) { - VA_COPY(preserve, args); - res = callback(u, i, preserve); - va_end(preserve); - count++; - if (res < 0) - break; - retval += res; - if (count >= 32767) { - if (count_ret) - *count_ret = count; - return retval; + else + { + if (!this->InvalidRange(list)) + { + delete this; + return; + } } } - if (res < -1) - break; - numstr += strcspn(numstr, ","); - if (*numstr) - numstr++; else - break; - } - if (count_ret) - *count_ret = count; + { + char *error2; + unsigned num1 = strtol(token.substr(0, t).c_str(), &error, 10); + unsigned num2 = strtol(token.substr(t + 1).c_str(), &error2, 10); + if (*error == '\0' && *error2 == '\0') + { + for (unsigned i = num1; i <= num2; ++i) + { + numbers.insert(i); + } + } + else + { + if (!this->InvalidRange(list)) + { + delete this; + return; + } + } + } + } while (sep.GetToken(token)); +} - va_end(args); +NumberList::~NumberList() +{ +} + +void NumberList::Process() +{ + if (this->desc) + { + for (std::set<unsigned>::reverse_iterator it = numbers.rbegin(); it != numbers.rend(); ++it) + { + this->HandleNumber(*it); + } + } + else + { + for (std::set<unsigned>::iterator it = numbers.begin(); it != numbers.end(); ++it) + { + this->HandleNumber(*it); + } + } + + delete this; +} - return retval; +void NumberList::HandleNumber(unsigned) +{ } -/*************************************************************************/ +bool NumberList::InvalidRange(const std::string &) +{ + return true; +} /** * dotime: Return the number of seconds corresponding to the given time @@ -804,16 +828,17 @@ int nickIsServices(const char *tempnick, int bot) found++; else if (Config.s_GlobalNoticer && (stricmp(nick, Config.s_GlobalNoticer) == 0)) found++; - else if (Config.s_BotServ && bot) { - BotInfo *bi; - int i; - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - ci::string ci_bi_nick(bi->nick.c_str()); - if (ci_bi_nick == nick) { - found++; - continue; - } + else if (Config.s_BotServ && bot) + { + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) + { + BotInfo *bi = it->second; + + ci::string ci_bi_nick(bi->nick.c_str()); + if (ci_bi_nick == nick) + { + found++; + break; } } } diff --git a/src/modes.cpp b/src/modes.cpp index 1685eea86..935d1e1b3 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -14,6 +14,9 @@ /* List of pairs of user/channels and their stacker info */ std::list<std::pair<void *, StackerInfo *> > ModeManager::StackerObjects; +/* List of all modes Anope knows about */ +std::list<Mode *> ModeManager::Modes; + /* User modes */ std::map<char, UserMode *> ModeManager::UserModesByChar; std::map<UserModeName, UserMode *> ModeManager::UserModesByName; @@ -21,18 +24,15 @@ std::map<UserModeName, UserMode *> ModeManager::UserModesByName; std::map<char, ChannelMode *> ModeManager::ChannelModesByChar; std::map<ChannelModeName, ChannelMode *> ModeManager::ChannelModesByName; /* Although there are two different maps for UserModes and ChannelModes - * the pointers in each are the same. This is used to increase - * efficiency. + * the pointers in each are the same. This is used to increase efficiency. */ -/* List of all modes Anope knows about */ -std::list<Mode *> ModeManager::Modes; /* Number of generic modes we support */ unsigned GenericChannelModes = 0, GenericUserModes = 0; /* Default mlocked modes on */ -std::bitset<128> DefMLockOn; +Flags<ChannelModeName> DefMLockOn; /* Default mlocked modes off */ -std::bitset<128> DefMLockOff; +Flags<ChannelModeName> DefMLockOff; /* Map for default mlocked mode parameters */ std::map<ChannelModeName, std::string> DefMLockParams; /* Modes to set on bots when they join the channel */ @@ -42,10 +42,10 @@ std::list<ChannelModeStatus *> BotModes; */ void SetDefaultMLock() { - DefMLockOn.reset(); - DefMLockOff.reset(); + DefMLockOn.ClearFlags(); + DefMLockOff.ClearFlags(); DefMLockParams.clear(); - std::bitset<128> *ptr = NULL; + Flags<ChannelModeName> *ptr = NULL; std::string modes, param; spacesepstream sep(Config.MLock); @@ -66,9 +66,9 @@ void SetDefaultMLock() if (cm && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM)) { - ptr->set(cm->Name); + ptr->SetFlag(cm->Name); - if (*ptr == DefMLockOn && cm->Type == MODE_PARAM) + if (ptr == &DefMLockOn && cm->Type == MODE_PARAM) { if (sep.GetToken(param)) { @@ -77,7 +77,7 @@ void SetDefaultMLock() else { Alog() << "Warning: Got default mlock mode " << cm->ModeChar << " with no param?"; - ptr->set(cm->Name, false); + ptr->UnsetFlag(cm->Name); } } } @@ -99,10 +99,11 @@ void SetDefaultMLock() /** Default constructor * @param mClass The type of mode this is + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param modeType The mode type */ -Mode::Mode(ModeClass mClass, char modeChar, ModeType modeType) : Class(mClass), ModeChar(modeChar), Type(modeType) +Mode::Mode(ModeClass mClass, const std::string &mNameAsString, char modeChar, ModeType modeType) : Class(mClass), NameAsString(mNameAsString), ModeChar(modeChar), Type(modeType) { } @@ -114,9 +115,10 @@ Mode::~Mode() /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ -UserMode::UserMode(UserModeName mName, char modeChar) : Mode(MC_USER, modeChar, MODE_REGULAR), Name(mName) +UserMode::UserMode(UserModeName mName, const std::string &mNameAsString, char modeChar) : Mode(MC_USER, mNameAsString, modeChar, MODE_REGULAR), Name(mName) { } @@ -128,18 +130,20 @@ UserMode::~UserMode() /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ -UserModeParam::UserModeParam(UserModeName mName, char modeChar) : UserMode(mName, modeChar) +UserModeParam::UserModeParam(UserModeName mName, const std::string &mNameAsString, char modeChar) : UserMode(mName, mNameAsString, modeChar) { this->Type = MODE_PARAM; } /** Default constrcutor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ -ChannelMode::ChannelMode(ChannelModeName mName, char modeChar) : Mode(MC_CHANNEL, modeChar, MODE_REGULAR), Name(mName) +ChannelMode::ChannelMode(ChannelModeName mName, const std::string &mNameAsString, char modeChar) : Mode(MC_CHANNEL, mNameAsString, modeChar, MODE_REGULAR), Name(mName) { } @@ -151,9 +155,10 @@ ChannelMode::~ChannelMode() /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char */ -ChannelModeList::ChannelModeList(ChannelModeName mName, char modeChar) : ChannelMode(mName, modeChar) +ChannelModeList::ChannelModeList(ChannelModeName mName, const std::string &mNameAsString, char modeChar) : ChannelMode(mName, mNameAsString, modeChar) { this->Type = MODE_LIST; } @@ -166,10 +171,11 @@ ChannelModeList::~ChannelModeList() /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param MinusArg true if the mode sends no arg when unsetting */ -ChannelModeParam::ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg) : ChannelMode(mName, modeChar), MinusNoArg(MinusArg) +ChannelModeParam::ChannelModeParam(ChannelModeName mName, const std::string &mNameAsString, char modeChar, bool MinusArg) : ChannelMode(mName, mNameAsString, modeChar), MinusNoArg(MinusArg) { this->Type = MODE_PARAM; } @@ -182,10 +188,11 @@ ChannelModeParam::~ChannelModeParam() /** Default constructor * @param mName The mode name + * @param mNameAsString The mode name as a string * @param modeChar The mode char * @param mSymbol The symbol for the mode, eg @ % + */ -ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol) : ChannelMode(mName, modeChar), Symbol(mSymbol) +ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, const std::string &mNameAsString, char modeChar, char mSymbol) : ChannelMode(mName, mNameAsString, modeChar), Symbol(mSymbol) { this->Type = MODE_STATUS; } diff --git a/src/module.cpp b/src/module.cpp index 4582ac069..b30e2b6a7 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -24,31 +24,12 @@ Module::Module(const std::string &mname, const std::string &creator) this->lang[i].argc = 0; } - int index = 0; - ModuleHash *current = NULL; - ModuleHash *newHash = NULL; - ModuleHash *lastHash = NULL; - - index = CMD_HASH(this->name); - - for (current = MODULE_HASH[index]; current; current = current->next) { - if (this->name ==current->name) - throw CoreException("Module already exists!"); - lastHash = current; - } - - if (!(newHash = new ModuleHash)) { - fatal("Out of memory"); - } + if (FindModule(this->name)) + throw CoreException("Module already exists!"); + this->created = time(NULL); - newHash->next = NULL; - newHash->name = sstrdup(this->name.c_str()); - newHash->m = this; - - if (lastHash == NULL) - MODULE_HASH[index] = newHash; - else - lastHash->next = newHash; + + Modules.push_back(this); } Module::~Module() @@ -60,85 +41,91 @@ Module::~Module() remove(this->filename.c_str()); - int idx; - CommandHash *current = NULL; - - Command *c; - /* Clear any active callbacks this module has */ ModuleManager::ClearCallBacks(this); /** * ok, im going to walk every hash looking for commands we own, now, not exactly elegant or efficiant :) **/ - for (idx = 0; idx < MAX_CMD_HASH; idx++) { - for (current = HS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(HOSTSERV, c->name.c_str()); - } - } + if (HostServ) + { + for (std::map<ci::string, Command *>::iterator it = HostServ->Commands.begin(); it != HostServ->Commands.end();) + { + Command *c = it->second; + ++it; + + if (c->module == this) + this->DelCommand(HostServ, c); } + } + + if (BotServ) + { + for (std::map<ci::string, Command *>::iterator it = BotServ->Commands.begin(); it != BotServ->Commands.end();) + { + Command *c = it->second; + ++it; - for (current = BS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(BOTSERV, c->name.c_str()); - } - } + if (c->module == this) + this->DelCommand(BotServ, c); } + } + + if (MemoServ) + { + for (std::map<ci::string, Command *>::iterator it = MemoServ->Commands.begin(); it != MemoServ->Commands.end();) + { + Command *c = it->second; + ++it; - for (current = MS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(MEMOSERV, c->name.c_str()); - } - } + if (c->module == this) + this->DelCommand(MemoServ, c); } + } + + if (NickServ) + { + for (std::map<ci::string, Command *>::iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end();) + { + Command *c = it->second; + ++it; - for (current = NS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(NICKSERV, c->name.c_str()); - } - } + if (c->module == this) + this->DelCommand(NickServ, c); } + } + + if (ChanServ) + { + for (std::map<ci::string, Command *>::iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end();) + { + Command *c = it->second; + ++it; - for (current = CS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(CHANSERV, c->name.c_str()); - } - } + if (c->module == this) + this->DelCommand(ChanServ, c); } + } - for (current = OS_cmdTable[idx]; current; current = current->next) { - for (c = current->c; c; c = c->next) { - if ((c->mod_name) && (stricmp(c->mod_name, this->name.c_str()) == 0)) { - this->DelCommand(OPERSERV, c->name.c_str()); - } - } + if (OperServ) + { + for (std::map<ci::string, Command *>::iterator it = OperServ->Commands.begin(); it != OperServ->Commands.end();) + { + Command *c = it->second; + ++it; + + if (c->module == this) + this->DelCommand(OperServ, c); } } - int index = 0; - ModuleHash *lastHash = NULL; - ModuleHash *mhash = NULL; - - index = CMD_HASH(this->name); - - for (mhash = MODULE_HASH[index]; mhash; mhash = mhash->next) { - if (this->name == mhash->name) { - if (!lastHash) { - MODULE_HASH[index] = mhash->next; - } else { - lastHash->next = mhash->next; - } - delete [] mhash->name; - delete mhash; + for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it) + { + if (*it == this) + { + Modules.erase(it); break; } - lastHash = mhash; } } diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index a9f1eb2f0..b11ad2829 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -18,7 +18,7 @@ void ModuleManager::LoadModuleList(std::list<std::string> &ModuleList) { for (std::list<std::string>::iterator it = ModuleList.begin(); it != ModuleList.end(); ++it) { - Module *m = findModule(it->c_str()); + Module *m = FindModule(*it); if (!m) ModuleManager::LoadModule(*it, NULL); } @@ -79,16 +79,13 @@ static int moduleCopyFile(const char *name, const char *output) static bool IsOneOfModuleTypeLoaded(MODType mt) { - int idx = 0; - ModuleHash *current = NULL; int pmods = 0; - for (idx = 0; idx != MAX_CMD_HASH; idx++) + for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it) { - for (current = MODULE_HASH[idx]; current; current = current->next) + if ((*it)->type == mt) { - if (current->m->type == mt) - pmods++; + ++pmods; } } @@ -127,7 +124,7 @@ int ModuleManager::LoadModule(const std::string &modname, User * u) if (modname.empty()) return MOD_ERR_PARAMS; - if (findModule(modname.c_str()) != NULL) + if (FindModule(modname) != NULL) return MOD_ERR_EXISTS; Alog(LOG_DEBUG) << "trying to load [" << modname << "]"; @@ -164,10 +161,10 @@ int ModuleManager::LoadModule(const std::string &modname, User * u) } ano_modclearerr(); - func = function_cast<Module *(*)(const std::string &, const std::string &)>(dlsym(handle, "init_module")); + func = function_cast<Module *(*)(const std::string &, const std::string &)>(dlsym(handle, "AnopeInit")); if (func == NULL && (err = dlerror()) != NULL) { - Alog() << "No magical init function found, not an Anope module"; + Alog() << "No init function found, not an Anope module"; dlclose(handle); return MOD_ERR_NOLOAD; } @@ -235,7 +232,7 @@ int ModuleManager::LoadModule(const std::string &modname, User * u) if (u) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s loaded module %s", u->nick.c_str(), modname.c_str()); + ircdproto->SendGlobops(OperServ, "%s loaded module %s", u->nick.c_str(), modname.c_str()); notice_lang(Config.s_OperServ, u, OPER_MODULE_LOADED, modname.c_str()); /* If a user is loading this module, then the core databases have already been loaded @@ -267,7 +264,7 @@ int ModuleManager::UnloadModule(Module *m, User *u) if (u) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s unloaded module %s", u->nick.c_str(), m->name.c_str()); + ircdproto->SendGlobops(OperServ, "%s unloaded module %s", u->nick.c_str(), m->name.c_str()); notice_lang(Config.s_OperServ, u, OPER_MODULE_UNLOADED, m->name.c_str()); } @@ -292,10 +289,10 @@ void ModuleManager::DeleteModule(Module *m) handle = m->handle; ano_modclearerr(); - destroy_func = function_cast<void (*)(Module *)>(dlsym(m->handle, "destroy_module")); + destroy_func = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini")); if (destroy_func == NULL && (err = dlerror()) != NULL) { - Alog() << "No magical destroy function found, chancing delete..."; + Alog() << "No destroy function found, chancing delete..."; delete m; /* we just have to chance they haven't overwrote the delete operator then... */ } else @@ -468,3 +465,21 @@ void ModuleManager::ClearCallBacks(Module *m) delete m->CallBacks.front(); } +/** Unloading all modules, NEVER call this when Anope isn't shutting down. + * Ever. + * @param unload_proto true to unload the protocol module + */ +void ModuleManager::UnloadAll(bool unload_proto) +{ + for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end();) + { + Module *m = *it++; + + if (unload_proto || m->type != PROTOCOL) + DeleteModule(m); + + if (Modules.empty()) + break; + } +} + diff --git a/src/modules.c b/src/modules.c deleted file mode 100644 index 40c10144f..000000000 --- a/src/modules.c +++ /dev/null @@ -1,784 +0,0 @@ -/* Modular support - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ -#include "modules.h" -#include "language.h" -#include "version.h" - -/** - * Declare all the list's we want to use here - **/ -CommandHash *HOSTSERV[MAX_CMD_HASH]; -CommandHash *BOTSERV[MAX_CMD_HASH]; -CommandHash *MEMOSERV[MAX_CMD_HASH]; -CommandHash *NICKSERV[MAX_CMD_HASH]; -CommandHash *CHANSERV[MAX_CMD_HASH]; -CommandHash *OPERSERV[MAX_CMD_HASH]; -MessageHash *IRCD[MAX_CMD_HASH]; -ModuleHash *MODULE_HASH[MAX_CMD_HASH]; - -char *mod_current_buffer = NULL; - -char *ModuleGetErrStr(int status) -{ - const char *module_err_str[] = { - "Module, Okay - No Error", /* MOD_ERR_OK */ - "Module Error, Allocating memory", /* MOD_ERR_MEMORY */ - "Module Error, Not enough parameters", /* MOD_ERR_PARAMS */ - "Module Error, Already loaded", /* MOD_ERR_EXISTS */ - "Module Error, File does not exist", /* MOD_ERR_NOEXIST */ - "Module Error, No User", /* MOD_ERR_NOUSER */ - "Module Error, Error during load time or module returned MOD_STOP", /* MOD_ERR_NOLOAD */ - "Module Error, Unable to unload", /* MOD_ERR_NOUNLOAD */ - "Module Error, Incorrect syntax", /* MOD_ERR_SYNTAX */ - "Module Error, Unable to delete", /* MOD_ERR_NODELETE */ - "Module Error, Unknown Error occuried", /* MOD_ERR_UNKOWN */ - "Module Error, File I/O Error", /* MOD_ERR_FILE_IO */ - "Module Error, No Service found for request", /* MOD_ERR_NOSERVICE */ - "Module Error, No module name for request" /* MOD_ERR_NO_MOD_NAME */ - }; - return const_cast<char *>(module_err_str[status]); -} - - -/************************************************/ - -/** - * Load the ircd protocol module up - **/ -int protocol_module_init() -{ - int ret = 0; - - Alog() << "Loading IRCD Protocol Module: [" << Config.IRCDModule << "]"; - ret = ModuleManager::LoadModule(Config.IRCDModule, NULL); - - if (ret == MOD_ERR_OK) - { - findModule(Config.IRCDModule)->SetType(PROTOCOL); - /* This is really NOT the correct place to do config checks, but - * as we only have the ircd struct filled here, we have to over - * here. -GD - */ - if (ircd->ts6) - { - if (!Config.Numeric) - { - Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration."; - ret = -1; - } - else - { - ts6_uid_init(); - } - } - } - - return ret; -} - -/** - * Unload ALL loaded modules, no matter what kind of module it is. - * Do NEVER EVER, and i mean NEVER (and if that isn't clear enough - * yet, i mean: NEVER AT ALL) call this unless we're shutting down, - * or we'll fuck up Anope badly (protocol handling won't work for - * example). If anyone calls this function without a justified need - * for it, i reserve the right to break their legs in a painful way. - * And if that isn't enough discouragement, you'll wake up with your - * both legs broken tomorrow ;) -GD - */ -void modules_unload_all(bool unload_proto) -{ - int idx; - ModuleHash *mh, *next; - - for (idx = 0; idx < MAX_CMD_HASH; idx++) { - mh = MODULE_HASH[idx]; - while (mh) { - next = mh->next; - if (unload_proto || (mh->m->type != PROTOCOL)) - ModuleManager::UnloadModule(mh->m, NULL); - mh = next; - } - } -} - -void Module::InsertLanguage(int langNumber, int ac, const char **av) -{ - int i; - - Alog(LOG_DEBUG) << this->name << "Adding " << ac << " texts for language " << langNumber; - - if (this->lang[langNumber].argc > 0) { - this->DeleteLanguage(langNumber); - } - - this->lang[langNumber].argc = ac; - this->lang[langNumber].argv = new char *[ac]; - for (i = 0; i < ac; i++) { - this->lang[langNumber].argv[i] = sstrdup(av[i]); - } -} - -/** - * Search the list of loaded modules for the given name. - * @param name the name of the module to find - * @return a pointer to the module found, or NULL - */ -Module *findModule(const char *name) -{ - int idx; - ModuleHash *current = NULL; - if (!name) { - return NULL; - } - idx = CMD_HASH(name); - - for (current = MODULE_HASH[idx]; current; current = current->next) { - if (stricmp(name, current->name) == 0) { - return current->m; - } - } - return NULL; - -} - -/******************************************************************************* - * Command Functions - *******************************************************************************/ - -/** Add a command to a command table. Only for internal use. - * only add if were unique, pos = 0; - * if we want it at the "head" of that command, pos = 1 - * at the tail, pos = 2 - * @param cmdTable the table to add the command to - * @param c the command to add - * @return MOD_ERR_OK will be returned on success. - */ -static int internal_addCommand(Module *m, CommandHash * cmdTable[], Command * c) -{ - /* We can assume both param's have been checked by this point.. */ - int index = 0; - CommandHash *current = NULL; - CommandHash *newHash = NULL; - CommandHash *lastHash = NULL; - - if (!cmdTable || !c) { - return MOD_ERR_PARAMS; - } - - index = CMD_HASH(c->name.c_str()); - - for (current = cmdTable[index]; current; current = current->next) { - if ((c->service) && (current->c) && (current->c->service) - && (!strcmp(c->service, current->c->service) == 0)) { - continue; - } - if ((stricmp(c->name.c_str(), current->name) == 0)) - { - /* the cmd exists, throw an error */ - return MOD_ERR_EXISTS; - } - lastHash = current; - } - - newHash = new CommandHash; - newHash->next = NULL; - newHash->name = sstrdup(c->name.c_str()); - newHash->c = c; - - if (lastHash == NULL) - cmdTable[index] = newHash; - else - lastHash->next = newHash; - - return MOD_ERR_OK; -} - -int Module::AddCommand(CommandHash * cmdTable[], Command * c) -{ - int status; - - if (!cmdTable || !c) { - return MOD_ERR_PARAMS; - } - c->core = 0; - if (!c->mod_name) { - c->mod_name = sstrdup(this->name.c_str()); - } - - - if (cmdTable == HOSTSERV) { - if (Config.s_HostServ) { - c->service = sstrdup(Config.s_HostServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else if (cmdTable == BOTSERV) { - if (Config.s_BotServ) { - c->service = sstrdup(Config.s_BotServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else if (cmdTable == MEMOSERV) { - if (Config.s_MemoServ) { - c->service = sstrdup(Config.s_MemoServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else if (cmdTable == CHANSERV) { - if (Config.s_ChanServ) { - c->service = sstrdup(Config.s_ChanServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else if (cmdTable == NICKSERV) { - if (Config.s_NickServ) { - c->service = sstrdup(Config.s_NickServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else if (cmdTable == OPERSERV) { - if (Config.s_OperServ) { - c->service = sstrdup(Config.s_OperServ); - } else { - return MOD_ERR_NOSERVICE; - } - } else - c->service = sstrdup("Unknown"); - - status = internal_addCommand(this, cmdTable, c); - if (status != MOD_ERR_OK) - { - Alog() << "ERROR! [ "<< status << "]"; - } - return status; -} - - -/** Remove a command from the command hash. Only for internal use. - * @param cmdTable the command table to remove the command from - * @param c the command to remove - * @param mod_name the name of the module who owns the command - * @return MOD_ERR_OK will be returned on success - */ -static int internal_delCommand(CommandHash * cmdTable[], Command * c, const char *mod_name) -{ - int index = 0; - CommandHash *current = NULL; - CommandHash *lastHash = NULL; - Command *tail = NULL, *last = NULL; - - if (!c || !cmdTable) { - return MOD_ERR_PARAMS; - } - - index = CMD_HASH(c->name.c_str()); - for (current = cmdTable[index]; current; current = current->next) { - if (stricmp(c->name.c_str(), current->name) == 0) { - if (!lastHash) { - tail = current->c; - if (tail->next) { - while (tail) { - if (mod_name && tail->mod_name - && (stricmp(mod_name, tail->mod_name) == 0)) { - if (last) { - last->next = tail->next; - } else { - current->c = tail->next; - } - return MOD_ERR_OK; - } - last = tail; - tail = tail->next; - } - } else { - cmdTable[index] = current->next; - delete [] current->name; - return MOD_ERR_OK; - } - } else { - tail = current->c; - if (tail->next) { - while (tail) { - if (mod_name && tail->mod_name - && (stricmp(mod_name, tail->mod_name) == 0)) { - if (last) { - last->next = tail->next; - } else { - current->c = tail->next; - } - return MOD_ERR_OK; - } - last = tail; - tail = tail->next; - } - } else { - lastHash->next = current->next; - delete [] current->name; - return MOD_ERR_OK; - } - } - } - lastHash = current; - } - return MOD_ERR_NOEXIST; -} - -/** - * Delete a command from the service given. - * @param cmdTable the cmdTable for the services to remove the command from - * @param name the name of the command to delete from the service - * @return returns MOD_ERR_OK on success - */ -int Module::DelCommand(CommandHash * cmdTable[], const char *dname) -{ - Command *c = NULL; - Command *cmd = NULL; - int status = 0; - - c = findCommand(cmdTable, dname); - if (!c) { - return MOD_ERR_NOEXIST; - } - - - for (cmd = c; cmd; cmd = cmd->next) - { - if (cmd->mod_name && cmd->mod_name == this->name) - { - status = internal_delCommand(cmdTable, cmd, this->name.c_str()); - } - } - return status; -} - -/** - * Search the command table gieven for a command. - * @param cmdTable the name of the command table to search - * @param name the name of the command to look for - * @return returns a pointer to the found command struct, or NULL - */ -Command *findCommand(CommandHash * cmdTable[], const char *name) -{ - int idx; - CommandHash *current = NULL; - if (!cmdTable || !name) { - return NULL; - } - - idx = CMD_HASH(name); - - for (current = cmdTable[idx]; current; current = current->next) { - if (stricmp(name, current->name) == 0) { - return current->c; - } - } - return NULL; -} - -/******************************************************************************* - * Message Functions - *******************************************************************************/ - - /** - * Create a new Message struct. - * @param name the name of the message - * @param func a pointer to the function to call when we recive this message - * @return a new Message object - **/ -Message *createMessage(const char *name, - int (*func) (const char *source, int ac, const char **av)) -{ - Message *m = NULL; - if (!name || !func) { - return NULL; - } - if (!(m = new Message)) { - fatal("Out of memory!"); - } - m->name = sstrdup(name); - m->func = func; - m->core = 0; - m->next = NULL; - return m; -} - -/** - * find a message in the given table. - * Looks up the message <name> in the MessageHash given - * @param MessageHash the message table to search for this command, will almost always be IRCD - * @param name the name of the command were looking for - * @return NULL if we cant find it, or a pointer to the Message if we can - **/ -Message *findMessage(MessageHash * msgTable[], const char *name) -{ - int idx; - MessageHash *current = NULL; - if (!msgTable || !name) { - return NULL; - } - idx = CMD_HASH(name); - - for (current = msgTable[idx]; current; current = current->next) { - if (stricmp(name, current->name) == 0) { - return current->m; - } - } - return NULL; -} - -/** - * Add a message to the MessageHash. - * @param msgTable the MessageHash we want to add a message to - * @param m the Message we want to add - * @param pos the position we want to add the message to, E.G. MOD_HEAD, MOD_TAIL, MOD_UNIQUE - * @return MOD_ERR_OK on a successful add. - **/ - -int addMessage(MessageHash * msgTable[], Message * m, int pos) -{ - /* We can assume both param's have been checked by this point.. */ - int index = 0; - MessageHash *current = NULL; - MessageHash *newHash = NULL; - MessageHash *lastHash = NULL; - Message *tail = NULL; - int match = 0; - - if (!msgTable || !m || (pos < 0 || pos > 2)) { - return MOD_ERR_PARAMS; - } - - index = CMD_HASH(m->name); - - for (current = msgTable[index]; current; current = current->next) { - match = stricmp(m->name, current->name); - if (match == 0) { /* the msg exist's we are a addHead */ - if (pos == 1) { - m->next = current->m; - current->m = m; - Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(m->next) - << "), new msg (" << static_cast<void *>(m) << ")"; - return MOD_ERR_OK; - } else if (pos == 2) { - tail = current->m; - while (tail->next) - tail = tail->next; - Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(tail) - << "), new msg (" << static_cast<void *>(m) << ")"; - m->next = NULL; - return MOD_ERR_OK; - } else - return MOD_ERR_EXISTS; - } - lastHash = current; - } - - if (!(newHash = new MessageHash)) { - fatal("Out of memory"); - } - newHash->next = NULL; - newHash->name = sstrdup(m->name); - newHash->m = m; - - if (lastHash == NULL) - msgTable[index] = newHash; - else - lastHash->next = newHash; - return MOD_ERR_OK; -} - -/** - * Add the given message (m) to the MessageHash marking it as a core command - * @param msgTable the MessageHash we want to add to - * @param m the Message we are adding - * @return MOD_ERR_OK on a successful add. - **/ -int addCoreMessage(MessageHash * msgTable[], Message * m) -{ - if (!msgTable || !m) { - return MOD_ERR_PARAMS; - } - m->core = 1; - return addMessage(msgTable, m, 0); -} - -/** - * remove the given message from the given message hash, for the given module - * @param msgTable which MessageHash we are removing from - * @param m the Message we want to remove - * @return MOD_ERR_OK on success, althing else on fail. - **/ -int delMessage(MessageHash * msgTable[], Message * m) -{ - int index = 0; - MessageHash *current = NULL; - MessageHash *lastHash = NULL; - Message *tail = NULL, *last = NULL; - - if (!m || !msgTable) { - return MOD_ERR_PARAMS; - } - - index = CMD_HASH(m->name); - - for (current = msgTable[index]; current; current = current->next) { - if (stricmp(m->name, current->name) == 0) { - if (!lastHash) { - tail = current->m; - if (tail->next) { - while (tail) { - if (last) { - last->next = tail->next; - } else { - current->m = tail->next; - } - return MOD_ERR_OK; - } - } else { - msgTable[index] = current->next; - delete [] current->name; - return MOD_ERR_OK; - } - } else { - tail = current->m; - if (tail->next) { - while (tail) { - if (last) { - last->next = tail->next; - } else { - current->m = tail->next; - } - return MOD_ERR_OK; - } - } else { - lastHash->next = current->next; - delete [] current->name; - return MOD_ERR_OK; - } - } - } - lastHash = current; - } - return MOD_ERR_NOEXIST; -} - -/** - * Destory a message, freeing its memory. - * @param m the message to be destroyed - * @return MOD_ERR_SUCCESS on success - **/ -int destroyMessage(Message * m) -{ - if (!m) { - return MOD_ERR_PARAMS; - } - if (m->name) { - delete [] m->name; - } - m->func = NULL; - m->next = NULL; - return MOD_ERR_OK; -} - -/******************************************************************************* - * Module Callback Functions - *******************************************************************************/ - - /* Check the current version of anope against a given version number - * Specifiying -1 for minor,patch or build - * @param major The major version of anope, the first part of the verison number - * @param minor The minor version of anope, the second part of the version number - * @param patch The patch version of anope, the third part of the version number - * @param build The build revision of anope from SVN - * @return True if the version newer than the version specified. - **/ -bool moduleMinVersion(int major, int minor, int patch, int build) -{ - bool ret = false; - if (VERSION_MAJOR > major) { /* Def. new */ - ret = true; - } else if (VERSION_MAJOR == major) { /* Might be newer */ - if (minor == -1) { - return true; - } /* They dont care about minor */ - if (VERSION_MINOR > minor) { /* Def. newer */ - ret = true; - } else if (VERSION_MINOR == minor) { /* Might be newer */ - if (patch == -1) { - return true; - } /* They dont care about patch */ - if (VERSION_PATCH > patch) { - ret = true; - } else if (VERSION_PATCH == patch) { -#if 0 -// XXX - if (build == -1) { - return true; - } /* They dont care about build */ - if (VERSION_BUILD >= build) { - ret = true; - } -#endif - } - } - } - return ret; -} - -void Module::NoticeLang(const char *source, User * u, int number, ...) -{ - va_list va; - char buffer[4096], outbuf[4096]; - char *fmt = NULL; - int mlang = Config.NSDefLanguage; - char *s, *t, *buf; - - /* Find the users lang, and use it if we can */ - if (u && u->Account()) { - mlang = u->Account()->language; - } - - /* If the users lang isnt supported, drop back to English */ - if (this->lang[mlang].argc == 0) - { - mlang = LANG_EN_US; - } - - /* If the requested lang string exists for the language */ - if (this->lang[mlang].argc > number) { - fmt = this->lang[mlang].argv[number]; - - buf = sstrdup(fmt); - va_start(va, number); - vsnprintf(buffer, 4095, buf, va); - va_end(va); - s = buffer; - while (*s) { - t = s; - s += strcspn(s, "\n"); - if (*s) - *s++ = '\0'; - strscpy(outbuf, t, sizeof(outbuf)); - u->SendMessage(source, "%s", outbuf); - } - delete [] buf; - } else { - Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]"; - } -} - -const char *Module::GetLangString(User * u, int number) -{ - int mlang = Config.NSDefLanguage; - - /* Find the users lang, and use it if we can */ - if (u && u->Account()) - mlang = u->Account()->language; - - /* If the users lang isnt supported, drop back to English */ - if (this->lang[mlang].argc == 0) - mlang = LANG_EN_US; - - /* If the requested lang string exists for the language */ - if (this->lang[mlang].argc > number) { - return this->lang[mlang].argv[number]; - /* Return an empty string otherwise, because we might be used without - * the return value being checked. If we would return NULL, bad things - * would happen! - */ - } else { - Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]"; - return ""; - } -} - -void Module::DeleteLanguage(int langNumber) -{ - if (this->lang[langNumber].argc) - { - for (int idx = 0; idx > this->lang[langNumber].argc; idx++) - delete [] this->lang[langNumber].argv[idx]; - delete [] this->lang[langNumber].argv; - this->lang[langNumber].argc = 0; - } -} - -void ModuleRunTimeDirCleanUp() -{ -#ifndef _WIN32 - DIR *dirp; - struct dirent *dp; -#else - BOOL fFinished; - HANDLE hList; - TCHAR szDir[MAX_PATH + 1]; - WIN32_FIND_DATA FileData; - char buffer[_MAX_PATH]; -#endif - char dirbuf[BUFSIZE]; - char filebuf[BUFSIZE]; - - snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir.c_str()); - - Alog(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait"; - - -#ifndef _WIN32 - if ((dirp = opendir(dirbuf)) == NULL) - { - Alog(LOG_DEBUG) << "cannot open directory (" << dirbuf << ")"; - return; - } - while ((dp = readdir(dirp)) != NULL) { - if (dp->d_ino == 0) { - continue; - } - if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) { - continue; - } - snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name); - unlink(filebuf); - } - closedir(dirp); -#else - /* Get the current working directory: */ - if (_getcwd(buffer, _MAX_PATH) == NULL) - { - Alog(LOG_DEBUG) << "Unable to set Current working directory"; - } - snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf); - - hList = FindFirstFile(szDir, &FileData); - if (hList != INVALID_HANDLE_VALUE) { - fFinished = FALSE; - while (!fFinished) { - if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName); - DeleteFile(filebuf); - } - if (!FindNextFile(hList, &FileData)) { - if (GetLastError() == ERROR_NO_MORE_FILES) { - fFinished = TRUE; - } - } - } - } else { - Alog(LOG_DEBUG) << "Invalid File Handle. GetLastError() reports "<< static_cast<int>(GetLastError()); - } - FindClose(hList); -#endif - Alog(LOG_DEBUG) << "Module run time directory has been cleaned out"; -} - -/* EOF */ diff --git a/src/modules.cpp b/src/modules.cpp new file mode 100644 index 000000000..0044bcc56 --- /dev/null +++ b/src/modules.cpp @@ -0,0 +1,413 @@ +/* Modular support + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ +#include "modules.h" +#include "language.h" +#include "version.h" + +std::multimap<std::string, Message *> MessageMap; +std::deque<Module *> Modules; + +char *mod_current_buffer = NULL; + +char *ModuleGetErrStr(int status) +{ + const char *module_err_str[] = { + "Module, Okay - No Error", /* MOD_ERR_OK */ + "Module Error, Allocating memory", /* MOD_ERR_MEMORY */ + "Module Error, Not enough parameters", /* MOD_ERR_PARAMS */ + "Module Error, Already loaded", /* MOD_ERR_EXISTS */ + "Module Error, File does not exist", /* MOD_ERR_NOEXIST */ + "Module Error, No User", /* MOD_ERR_NOUSER */ + "Module Error, Error during load time or module returned MOD_STOP", /* MOD_ERR_NOLOAD */ + "Module Error, Unable to unload", /* MOD_ERR_NOUNLOAD */ + "Module Error, Incorrect syntax", /* MOD_ERR_SYNTAX */ + "Module Error, Unable to delete", /* MOD_ERR_NODELETE */ + "Module Error, Unknown Error occuried", /* MOD_ERR_UNKOWN */ + "Module Error, File I/O Error", /* MOD_ERR_FILE_IO */ + "Module Error, No Service found for request", /* MOD_ERR_NOSERVICE */ + "Module Error, No module name for request" /* MOD_ERR_NO_MOD_NAME */ + }; + return const_cast<char *>(module_err_str[status]); +} + + +/************************************************/ + +/** + * Load the ircd protocol module up + **/ +int protocol_module_init() +{ + int ret = 0; + + Alog() << "Loading IRCD Protocol Module: [" << Config.IRCDModule << "]"; + ret = ModuleManager::LoadModule(Config.IRCDModule, NULL); + + if (ret == MOD_ERR_OK) + { + FindModule(Config.IRCDModule)->SetType(PROTOCOL); + /* This is really NOT the correct place to do config checks, but + * as we only have the ircd struct filled here, we have to over + * here. -GD + */ + if (ircd->ts6) + { + if (!Config.Numeric) + { + Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration."; + ret = -1; + } + } + } + + return ret; +} + +void Module::InsertLanguage(int langNumber, int ac, const char **av) +{ + int i; + + Alog(LOG_DEBUG) << this->name << "Adding " << ac << " texts for language " << langNumber; + + if (this->lang[langNumber].argc > 0) { + this->DeleteLanguage(langNumber); + } + + this->lang[langNumber].argc = ac; + this->lang[langNumber].argv = new char *[ac]; + for (i = 0; i < ac; i++) { + this->lang[langNumber].argv[i] = sstrdup(av[i]); + } +} + +/** + * Search the list of loaded modules for the given name. + * @param name the name of the module to find + * @return a pointer to the module found, or NULL + */ +Module *FindModule(const std::string &name) +{ + for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it) + { + Module *m = *it; + + if (m->name == name) + { + return m; + } + } + + return NULL; +} + +/** Add a message to Anope + * @param name The message name as sent by the IRCd + * @param func A callback function that will be called when this message is received + * @return The new message object + */ +Message *Anope::AddMessage(const std::string &name, int (*func)(const char *source, int ac, const char **av)) +{ + Message *m = new Message; + + m->name = name; + m->func = func; + + MessageMap.insert(std::make_pair(m->name, m)); + + return m; +} + +/** Deletes a message from Anope + * XXX Im not sure what will happen if this function is called indirectly from a message function pointed to by this message and there + * is more than one hook for this message.. must check + * @param m The message + * @return true if the message was found and deleted, else false + */ +bool Anope::DelMessage(Message *m) +{ + std::multimap<std::string, Message *>::iterator it = MessageMap.find(m->name); + + if (it == MessageMap.end()) + { + return false; + } + + std::multimap<std::string, Message *>::iterator upper = MessageMap.upper_bound(m->name); + + for (; it != upper; ++it) + { + if (it->second == m) + { + delete m; + MessageMap.erase(it); + return true; + } + } + + return false; +} + +/******************************************************************************* + * Command Functions + *******************************************************************************/ + +int Module::AddCommand(BotInfo *bi, Command *c) +{ + if (!bi || !c) + return MOD_ERR_PARAMS; + + c->module = this; + c->service = bi; + + std::pair<std::map<ci::string, Command *>::iterator, bool> it = bi->Commands.insert(std::make_pair(c->name, c)); + + if (it.second != true) + { + Alog() << "Error creating command " << c->name << ". Command already exists!"; + delete c; + return MOD_ERR_EXISTS; + } + + return MOD_ERR_OK; +} + +/** + * Delete a command from the service given. + * @param cmdTable the cmdTable for the services to remove the command from + * @param name the name of the command to delete from the service + * @return returns MOD_ERR_OK on success + */ +int Module::DelCommand(BotInfo *bi, Command *c) +{ + if (!bi || !c) + return MOD_ERR_PARAMS; + + if (!bi->Commands.erase(c->name)) + return MOD_ERR_NOEXIST; + + return MOD_ERR_OK; +} + +/** + * Find a message in the message table + * @param name The name of the message were looking for + * @return NULL if we cant find it, or a pointer to the Message if we can + **/ +std::vector<Message *> FindMessage(const std::string &name) +{ + std::vector<Message *> messages; + + std::multimap<std::string, Message *>::iterator it = MessageMap.find(name); + + if (it == MessageMap.end()) + return messages; + + std::multimap<std::string, Message *>::iterator upper = MessageMap.upper_bound(name); + + for (; it != upper; ++it) + messages.push_back(it->second); + + return messages; +} + +/******************************************************************************* + * Module Callback Functions + *******************************************************************************/ + + /* Check the current version of anope against a given version number + * Specifiying -1 for minor,patch or build + * @param major The major version of anope, the first part of the verison number + * @param minor The minor version of anope, the second part of the version number + * @param patch The patch version of anope, the third part of the version number + * @param build The build revision of anope from SVN + * @return True if the version newer than the version specified. + **/ +bool moduleMinVersion(int major, int minor, int patch, int build) +{ + bool ret = false; + if (VERSION_MAJOR > major) { /* Def. new */ + ret = true; + } else if (VERSION_MAJOR == major) { /* Might be newer */ + if (minor == -1) { + return true; + } /* They dont care about minor */ + if (VERSION_MINOR > minor) { /* Def. newer */ + ret = true; + } else if (VERSION_MINOR == minor) { /* Might be newer */ + if (patch == -1) { + return true; + } /* They dont care about patch */ + if (VERSION_PATCH > patch) { + ret = true; + } else if (VERSION_PATCH == patch) { +#if 0 +// XXX + if (build == -1) { + return true; + } /* They dont care about build */ + if (VERSION_BUILD >= build) { + ret = true; + } +#endif + } + } + } + return ret; +} + +void Module::NoticeLang(const char *source, User * u, int number, ...) +{ + va_list va; + char buffer[4096], outbuf[4096]; + char *fmt = NULL; + int mlang = Config.NSDefLanguage; + char *s, *t, *buf; + + /* Find the users lang, and use it if we can */ + if (u && u->Account()) { + mlang = u->Account()->language; + } + + /* If the users lang isnt supported, drop back to English */ + if (this->lang[mlang].argc == 0) + { + mlang = LANG_EN_US; + } + + /* If the requested lang string exists for the language */ + if (this->lang[mlang].argc > number) { + fmt = this->lang[mlang].argv[number]; + + buf = sstrdup(fmt); + va_start(va, number); + vsnprintf(buffer, 4095, buf, va); + va_end(va); + s = buffer; + while (*s) { + t = s; + s += strcspn(s, "\n"); + if (*s) + *s++ = '\0'; + strscpy(outbuf, t, sizeof(outbuf)); + u->SendMessage(source, "%s", outbuf); + } + delete [] buf; + } else { + Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]"; + } +} + +const char *Module::GetLangString(User * u, int number) +{ + int mlang = Config.NSDefLanguage; + + /* Find the users lang, and use it if we can */ + if (u && u->Account()) + mlang = u->Account()->language; + + /* If the users lang isnt supported, drop back to English */ + if (this->lang[mlang].argc == 0) + mlang = LANG_EN_US; + + /* If the requested lang string exists for the language */ + if (this->lang[mlang].argc > number) { + return this->lang[mlang].argv[number]; + /* Return an empty string otherwise, because we might be used without + * the return value being checked. If we would return NULL, bad things + * would happen! + */ + } else { + Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]"; + return ""; + } +} + +void Module::DeleteLanguage(int langNumber) +{ + if (this->lang[langNumber].argc) + { + for (int idx = 0; idx > this->lang[langNumber].argc; idx++) + delete [] this->lang[langNumber].argv[idx]; + delete [] this->lang[langNumber].argv; + this->lang[langNumber].argc = 0; + } +} + +void ModuleRunTimeDirCleanUp() +{ +#ifndef _WIN32 + DIR *dirp; + struct dirent *dp; +#else + BOOL fFinished; + HANDLE hList; + TCHAR szDir[MAX_PATH + 1]; + WIN32_FIND_DATA FileData; + char buffer[_MAX_PATH]; +#endif + char dirbuf[BUFSIZE]; + char filebuf[BUFSIZE]; + + snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir.c_str()); + + Alog(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait"; + + +#ifndef _WIN32 + if ((dirp = opendir(dirbuf)) == NULL) + { + Alog(LOG_DEBUG) << "cannot open directory (" << dirbuf << ")"; + return; + } + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_ino == 0) { + continue; + } + if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) { + continue; + } + snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name); + unlink(filebuf); + } + closedir(dirp); +#else + /* Get the current working directory: */ + if (_getcwd(buffer, _MAX_PATH) == NULL) + { + Alog(LOG_DEBUG) << "Unable to set Current working directory"; + } + snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf); + + hList = FindFirstFile(szDir, &FileData); + if (hList != INVALID_HANDLE_VALUE) { + fFinished = FALSE; + while (!fFinished) { + if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName); + DeleteFile(filebuf); + } + if (!FindNextFile(hList, &FileData)) { + if (GetLastError() == ERROR_NO_MORE_FILES) { + fFinished = TRUE; + } + } + } + } else { + Alog(LOG_DEBUG) << "Invalid File Handle. GetLastError() reports "<< static_cast<int>(GetLastError()); + } + FindClose(hList); +#endif + Alog(LOG_DEBUG) << "Module run time directory has been cleaned out"; +} + +/* EOF */ diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index ad66663c3..a7feab5d0 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -1,5 +1,4 @@ -# Find all the *.c and *.cpp files within the current source directory, and sort the list -file(GLOB MODULES_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") +# Find all the *.cpp files within the current source directory, and sort the list file(GLOB MODULES_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") set(MODULES_SRCS ${MODULES_SRCS_C} ${MODULES_SRCS_CPP}) sort_list(MODULES_SRCS) @@ -58,6 +57,7 @@ endforeach(SRC) file(GLOB MODULES_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*") remove_item_from_list(MODULES_FILES "CMakeFiles") remove_item_from_list(MODULES_FILES "mysql") +remove_item_from_list(MODULES_FILES "ssl") # Iterate through this directory searching for subdirectories, and creating modules for those subdirectories foreach(FILE ${MODULES_FILES}) diff --git a/src/modules/Makefile b/src/modules/Makefile index 3ab2a7803..c69128ea3 100644 --- a/src/modules/Makefile +++ b/src/modules/Makefile @@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}'\ 'MAKEBIN=${MAKEBIN}' 'MYSQLDIR=${MYSQLDIR}' -OBJECTS= $(SRCS:.c=.so) -OBJECTS+= $(SRCS:.cpp=.so) +OBJECTS= $(SRCS:.cpp=.so) CDEFS= -rdynamic -Wall MYSQL_ARGS = -I$(MYSQLDIR)/include/ -L$(MYSQLDIR)/lib/ -Wl,-rpath -Wl,$(MYSQLDIR)/lib/ -lmysqlpp @@ -25,16 +24,11 @@ install: distclean: spotless -.SUFFIXES: .c .cpp .so - -.c.so: - $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} \ - $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) \ - -I../${INCLUDEDIR} -o $@ $< +.SUFFIXES: .cpp .so .cpp.so: $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} \ - $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) \ + $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) $(if $(shell grep RequiredLibraries $< | grep ssl), -lssl) $(if $(shell grep RequiredLibraries $< | grep crypt), -lcrypt) \ -I../${INCLUDEDIR} -o $@ $< subs: diff --git a/src/modules/cs_appendtopic.c b/src/modules/cs_appendtopic.cpp index 22848b74a..a44e6d1a9 100644 --- a/src/modules/cs_appendtopic.c +++ b/src/modules/cs_appendtopic.cpp @@ -128,6 +128,11 @@ class CommandCSAppendTopic : public Command { me->NoticeLang(Config.s_ChanServ, u, LNG_APPENDTOPIC_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP); + } }; class CSAppendTopic : public Module @@ -141,7 +146,7 @@ class CSAppendTopic : public Module this->SetVersion(VERSION); this->SetType(SUPPORTED); - this->AddCommand(CHANSERV, new CommandCSAppendTopic()); + this->AddCommand(ChanServ, new CommandCSAppendTopic()); /* English (US) */ const char* langtable_en_us[] = { @@ -222,12 +227,6 @@ class CSAppendTopic : public Module this->InsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - this->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP); } }; diff --git a/src/modules/cs_enforce.c b/src/modules/cs_enforce.cpp index 435f07d79..271b9da05 100644 --- a/src/modules/cs_enforce.c +++ b/src/modules/cs_enforce.cpp @@ -216,6 +216,11 @@ class CommandCSEnforce : public Command { me->NoticeLang(Config.s_ChanServ, u, LNG_ENFORCE_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP); + } }; class CSEnforce : public Module @@ -229,7 +234,7 @@ class CSEnforce : public Module this->SetVersion(VERSION); this->SetType(SUPPORTED); - this->AddCommand(CHANSERV, new CommandCSEnforce()); + this->AddCommand(ChanServ, new CommandCSEnforce()); /* English (US) */ const char* langtable_en_us[] = { @@ -438,12 +443,6 @@ class CSEnforce : public Module this->InsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - this->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP); } }; diff --git a/src/modules/cs_tban.c b/src/modules/cs_tban.cpp index 10f295b3d..5a768dc81 100644 --- a/src/modules/cs_tban.c +++ b/src/modules/cs_tban.cpp @@ -83,6 +83,11 @@ class CommandCSTBan : public Command { me->NoticeLang(Config.s_ChanServ, u, TBAN_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_ChanServ, u, TBAN_HELP); + } }; class CSTBan : public Module @@ -92,7 +97,7 @@ class CSTBan : public Module { me = this; - this->AddCommand(CHANSERV, new CommandCSTBan()); + this->AddCommand(ChanServ, new CommandCSTBan()); this->SetAuthor(AUTHOR); this->SetVersion(VERSION); @@ -154,12 +159,6 @@ class CSTBan : public Module this->InsertLanguage(LANG_PT, LANG_NUM_STRINGS, langtable_pt); this->InsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru); this->InsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it); - - ModuleManager::Attach(I_OnChanServHelp, this); - } - void OnChanServHelp(User *u) - { - this->NoticeLang(Config.s_ChanServ, u, TBAN_HELP); } }; @@ -181,7 +180,7 @@ class TempBan : public CallBack { Channel *c; - if ((c = findchan(chan.c_str())) && c->ci) + if ((c = findchan(chan)) && c->ci) { c->RemoveMode(NULL, CMODE_BAN, mask); } @@ -203,7 +202,7 @@ int canBanUser(Channel * c, User * u, User * u2) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else if (is_excepted(ci, u2)) notice_lang(Config.s_ChanServ, u, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str()); - else if (is_protected(u2)) + else if (u2->IsProtected()) notice_lang(Config.s_ChanServ, u, ACCESS_DENIED); else ok = 1; diff --git a/src/modules/hs_request.c b/src/modules/hs_request.cpp index ebc46dfe8..cc5637bef 100644 --- a/src/modules/hs_request.c +++ b/src/modules/hs_request.cpp @@ -205,6 +205,11 @@ class CommandHSRequest : public Command { me->NoticeLang(Config.s_HostServ, u, LNG_REQUEST_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_HostServ, u, LNG_HELP); + } }; class CommandHSActivate : public Command @@ -257,6 +262,11 @@ class CommandHSActivate : public Command { me->NoticeLang(Config.s_HostServ, u, LNG_ACTIVATE_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_HostServ, u, LNG_HELP_SETTER); + } }; class CommandHSReject : public Command @@ -339,7 +349,7 @@ class HSListBase : public Command return MOD_CONT; } public: - HSListBase(const std::string &cmd, int min, int max) : Command(cmd, min, max, "hostserv/set") + HSListBase(const ci::string &cmd, int min, int max) : Command(cmd, min, max, "hostserv/set") { } @@ -378,10 +388,10 @@ class HSRequest : public Module { me = this; - this->AddCommand(HOSTSERV, new CommandHSRequest()); - this->AddCommand(HOSTSERV, new CommandHSActivate()); - this->AddCommand(HOSTSERV, new CommandHSReject()); - this->AddCommand(HOSTSERV, new CommandHSWaiting()); + this->AddCommand(HostServ, new CommandHSRequest()); + this->AddCommand(HostServ, new CommandHSActivate()); + this->AddCommand(HostServ, new CommandHSReject()); + this->AddCommand(HostServ, new CommandHSWaiting()); this->SetAuthor(AUTHOR); this->SetVersion(VERSION); @@ -645,8 +655,8 @@ class HSRequest : public Module this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); - Implementation i[] = { I_OnHostServHelp, I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite }; - ModuleManager::Attach(i, this, 4); + Implementation i[] = { I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite }; + ModuleManager::Attach(i, this, 3); } ~HSRequest() @@ -670,7 +680,7 @@ class HSRequest : public Module if (!key.empty() && key == "+req") { std::vector<ci::string> emptyParams; - Command *c = findCommand(HOSTSERV, "WAITING"); + Command *c = FindCommand(HostServ, "WAITING"); c->Execute(u, emptyParams); return EVENT_STOP; } @@ -698,12 +708,6 @@ class HSRequest : public Module return EVENT_CONTINUE; } - void OnHostServHelp(User *u) - { - this->NoticeLang(Config.s_HostServ, u, LNG_HELP); - this->NoticeLang(Config.s_HostServ, u, LNG_HELP_SETTER); - } - EventReturn OnDatabaseRead(const std::vector<std::string> ¶ms) { if (params[0] == "HS_REQUEST" && params.size() >= 5) diff --git a/src/modules/mysql/db_mysql.h b/src/modules/mysql/db_mysql.h index b62f52524..f2885408f 100644 --- a/src/modules/mysql/db_mysql.h +++ b/src/modules/mysql/db_mysql.h @@ -39,48 +39,6 @@ NickCoreFlagInfo NickCoreFlags[] = { {"", static_cast<NickCoreFlag>(-1)} }; -struct ChannelModeInfo -{ - std::string Name; - ChannelModeName Mode; -}; - -ChannelModeInfo ChannelModes[] = { - {"CMODE_BLOCKCOLOR", CMODE_BLOCKCOLOR}, - {"CMODE_FLOOD", CMODE_FLOOD}, - {"CMODE_INVITE", CMODE_INVITE}, - {"CMODE_KEY", CMODE_KEY}, - {"CMODE_LIMIT", CMODE_LIMIT}, - {"CMODE_MODERATED", CMODE_MODERATED}, - {"CMODE_NOEXTERNAL", CMODE_NOEXTERNAL}, - {"CMODE_PRIVATE", CMODE_PRIVATE}, - {"CMODE_REGISTERED", CMODE_REGISTERED}, - {"CMODE_SECRET", CMODE_SECRET}, - {"CMODE_TOPIC", CMODE_TOPIC}, - {"CMODE_AUDITORIUM", CMODE_AUDITORIUM}, - {"CMODE_SSL", CMODE_SSL}, - {"CMODE_ADMINONLY", CMODE_ADMINONLY}, - {"CMODE_NOCTCP", CMODE_NOCTCP}, - {"CMODE_FILTER", CMODE_FILTER}, - {"CMODE_NOKNOCK", CMODE_NOKNOCK}, - {"CMODE_REDIRECT", CMODE_REDIRECT}, - {"CMODE_REGMODERATED", CMODE_REGMODERATED}, - {"CMODE_NONICK", CMODE_NONICK}, - {"CMODE_OPERONLY", CMODE_OPERONLY}, - {"CMODE_NONICK", CMODE_NONICK}, - {"CMODE_REGISTEREDONLY", CMODE_REGISTEREDONLY}, - {"CMODE_STRIPCOLOR", CMODE_STRIPCOLOR}, - {"CMODE_NONOTICE", CMODE_NONOTICE}, - {"CMODE_NOINVITE", CMODE_NOINVITE}, - {"CMODE_ALLINVITE", CMODE_ALLINVITE}, - {"CMODE_BLOCKCAPS", CMODE_BLOCKCAPS}, - {"CMODE_PERM", CMODE_PERM}, - {"CMODE_NICKFLOOD", CMODE_NICKFLOOD}, - {"CMODE_JOINFLOOD", CMODE_JOINFLOOD}, - {"CMODE_NOREJOIN", CMODE_NOREJOIN}, - {"", static_cast<ChannelModeName>(-1)} -}; - struct BotFlagInfo { std::string Name; @@ -140,13 +98,6 @@ struct BotServFlagInfo BotServFlagInfo BotServFlags[] = { {"PRIVATE", BI_PRIVATE}, - {"CHANSERV", BI_CHANSERV}, - {"BOTSERV", BI_BOTSERV}, - {"HOSTSERV", BI_HOSTSERV}, - {"OPERSERV", BI_OPERSERV}, - {"MEMOSERV", BI_MEMOSERV}, - {"NICKSERV", BI_NICKSERV}, - {"GLOBAL", BI_GLOBAL}, {"", static_cast<BotFlag>(-1)} }; @@ -169,7 +120,7 @@ MemoFlagInfo MemoFlags[] = { inline std::string SQLAssign(const mysqlpp::String& s) { return s.c_str(); } class DBMySQL; -static DBMySQL *Me; +static DBMySQL *me; bool ExecuteQuery(mysqlpp::Query& query) { @@ -226,7 +177,7 @@ class DBMySQL : public Module DBMySQL(const std::string &modname, const std::string &creator) : Module(modname, creator) { - Me = this; + me = this; this->SetAuthor("Anope"); this->SetVersion(VERSION_STRING); diff --git a/src/modules/mysql/db_mysql_execute.cpp b/src/modules/mysql/db_mysql_execute.cpp index 0c7c4de65..2313edd37 100644 --- a/src/modules/mysql/db_mysql_execute.cpp +++ b/src/modules/mysql/db_mysql_execute.cpp @@ -1,24 +1,18 @@ /* RequiredLibraries: mysqlpp */ #include "db_mysql.h" -#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31)) class FakeNickCore : public NickCore { public: FakeNickCore() : NickCore("-SQLUser") { - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - nclists[HASH(this->display)] = this->next; + NickCoreList.erase(this->display); } ~FakeNickCore() { - insert_core(this); + NickCoreList[this->display] = this; Users.clear(); } @@ -37,27 +31,17 @@ class FakeUser : public User this->realname = sstrdup("Fake SQL User"); this->hostip = sstrdup("255.255.255.255"); this->vhost = NULL; - this->server = serv_uplink; // XXX Need a good way to set this to ourself - - if (this->prev) - this->prev->next = this->next; - else - userlist[HASH(this->nick.c_str())] = this->next; - if (this->next) - this->next->prev = this->prev; + this->server = Me; + + UserListByNick.erase("-SQLUser"); --usercnt; } ~FakeUser() { - this->server = serv_uplink; // XXX Need a good way to set this to ourself - - User **list = &userlist[HASH(this->nick.c_str())]; - this->next = *list; - if (*list) - (*list)->prev = this; - *list = this; + UserListByNick["-SQLUser"] = this; ++usercnt; + nc = NULL; } @@ -68,21 +52,22 @@ class FakeUser : public User NickCore *Account() const { return nc; } const bool IsIdentified(bool) const { return nc ? true : false; } + const bool IsRecognized(bool) const { return true; } } SQLUser; class SQLTimer : public Timer { public: - SQLTimer() : Timer(Me->Delay, time(NULL), true) + SQLTimer() : Timer(me->Delay, time(NULL), true) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "TRUNCATE TABLE `anope_commands`"; ExecuteQuery(query); } void Tick(time_t) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); mysqlpp::StoreQueryResult qres; query << "SELECT * FROM `anope_commands`"; @@ -144,11 +129,7 @@ class SQLTimer : public Timer continue; } - // XXX this whole strtok thing needs to die - char *cmdbuf = sstrdup(qres[i]["command"].c_str()); - char *cmd = strtok(cmdbuf, " "); - mod_run_cmd(bi->nick, u, bi->cmdTable, cmd); - delete [] cmdbuf; + mod_run_cmd(bi, u, qres[i]["command"].c_str()); if (logout) u->Logout(); @@ -171,7 +152,7 @@ class DBMySQLExecute : public DBMySQL ~DBMySQLExecute() { - TimerManager::DelTimer(_SQLTimer); + delete _SQLTimer; } }; diff --git a/src/modules/mysql/db_mysql_read.cpp b/src/modules/mysql/db_mysql_read.cpp index 5c498b008..3c5fb359a 100644 --- a/src/modules/mysql/db_mysql_read.cpp +++ b/src/modules/mysql/db_mysql_read.cpp @@ -27,7 +27,7 @@ static std::vector<std::string> MakeVector(std::string buf) static void LoadDatabase() { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); mysqlpp::StoreQueryResult qres; query << "SELECT * FROM `anope_ns_core`"; @@ -166,7 +166,13 @@ static void LoadDatabase() { for (size_t i = 0; i < qres.num_rows(); ++i) { - BotInfo *bi = new BotInfo(SQLAssign(qres[i]["nick"]), SQLAssign(qres[i]["user"]), SQLAssign(qres[i]["host"]), SQLAssign(qres[i]["rname"])); + BotInfo *bi = findbot(SQLAssign(qres[i]["nick"])); + if (!bi) + bi = new BotInfo(SQLAssign(qres[i]["nick"])); + bi->user = SQLAssign(qres[i]["user"]); + bi->host = SQLAssign(qres[i]["host"]); + bi->real = SQLAssign(qres[i]["rname"]); + if (qres[i]["flags"].size()) { spacesepstream sep(SQLAssign(qres[i]["flags"])); @@ -266,52 +272,37 @@ static void LoadDatabase() ci->bantype = atoi(qres[i]["bantype"].c_str()); if (qres[i]["mlock_on"].size()) { + std::vector<std::string> modes; std::string buf; + spacesepstream sep(SQLAssign(qres[i]["mlock_on"])); while (sep.GetToken(buf)) - { - for (int j = 0; ChannelModes[j].Mode != -1; ++j) - { - if (buf == ChannelModes[j].Name) - { - ci->SetMLock(ChannelModes[j].Mode, true); - break; - } - } - } + modes.push_back(buf); + + ci->Extend("db_mlock_modes_on", new ExtensibleItemRegular<std::vector<std::string> >(modes)); } if (qres[i]["mlock_off"].size()) { + std::vector<std::string> modes; std::string buf; + spacesepstream sep(SQLAssign(qres[i]["mlock_off"])); while (sep.GetToken(buf)) - { - for (int j = 0; ChannelModes[j].Mode != -1; ++j) - { - if (buf == ChannelModes[j].Name) - { - ci->SetMLock(ChannelModes[j].Mode, false); - break; - } - } - } + modes.push_back(buf); + + ci->Extend("db_mlock_modes_off", new ExtensibleItemRegular<std::vector<std::string> >(modes)); } if (qres[i]["mlock_params"].size()) { - std::string buf; + std::vector<std::pair<std::string, std::string> > mlp; + std::string buf, buf2; + spacesepstream sep(SQLAssign(qres[i]["mlock_params"])); - while (sep.GetToken(buf)) - { - for (int j = 0; ChannelModes[j].Mode != -1; ++j) - { - if (buf == ChannelModes[j].Name) - { - sep.GetToken(buf); - ci->SetMLock(ChannelModes[j].Mode, true, buf); - break; - } - } - } + + while (sep.GetToken(buf) && sep.GetToken(buf2)) + mlp.push_back(std::make_pair(buf, buf2)); + + ci->Extend("db_mlp", new ExtensibleItemRegular<std::vector<std::pair<std::string, std::string> > >(mlp)); } if (qres[i]["entry_message"].size()) ci->entry_message = sstrdup(qres[i]["entry_message"].c_str()); @@ -629,42 +620,51 @@ static void LoadDatabase() query << "SELECT * FROM `anope_os_akills`"; qres = StoreQuery(query); - if (qres) + if (qres && SGLine) { for (size_t i = 0; i < qres.size(); ++i) { - Akill *ak = new Akill; - ak->user = sstrdup(qres[i]["user"].c_str()); - ak->host = sstrdup(qres[i]["host"].c_str()); - ak->by = sstrdup(qres[i]["xby"].c_str()); - ak->reason = sstrdup(qres[i]["reason"].c_str()); - ak->seton = atol(qres[i]["seton"].c_str()); - ak->expires = atol(qres[i]["expire"].c_str()); - slist_add(&akills, ak); + ci::string user = qres[i]["user"].c_str(); + ci::string host = qres[i]["host"].c_str(); + ci::string by = qres[i]["xby"].c_str(); + std::string reason = SQLAssign(qres[i]["reason"]); + time_t seton = atol(qres[i]["seton"].c_str()); + time_t expires = atol(qres[i]["expire"].c_str()); + + XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason); + if (x) + { + x->By = by; + x->Created = seton; + } } } - query << "SELECT * FROM `anope_os_sxlines`"; + query << "SELECT * FROM `anope_os_xlines`"; qres = StoreQuery(query); if (qres) { for (size_t i = 0; i < qres.size(); ++i) { - SXLine *sx = new SXLine; - sx->mask = sstrdup(qres[i]["mask"].c_str()); - sx->by = sstrdup(qres[i]["xby"].c_str()); - sx->reason = sstrdup(qres[i]["reason"].c_str()); - sx->seton = atol(qres[i]["seton"].c_str()); - sx->expires = atol(qres[i]["expires"].c_str()); - if (qres[i]["type"] == "SGLINE") - slist_add(&sglines, sx); - else if (qres[i]["type"] == "SQLINE") - slist_add(&sqlines, sx); - else if (qres[i]["type"] == "SZLINE") - slist_add(&szlines, sx); - else - delete sx; + ci::string mask = qres[i]["mask"].c_str(); + ci::string by = qres[i]["xby"].c_str(); + std::string reason = SQLAssign(qres[i]["reason"]); + time_t seton = atol(qres[i]["seton"].c_str()); + time_t expires = atol(qres[i]["expires"].c_str()); + + XLine *x = NULL; + if (qres[i]["type"] == "SNLINE" && SNLine) + x = SNLine->Add(NULL, NULL, mask, expires, reason); + else if (qres[i]["type"] == "SQLINE" && SQLine) + x = SQLine->Add(NULL, NULL, mask, expires, reason); + else if (qres[i]["type"] == "SZLINE" && SZLine) + x = SZLine->Add(NULL, NULL,mask, expires, reason); + if (x) + { + x->By = by; + x->Created = seton; + } } } } diff --git a/src/modules/mysql/db_mysql_write.cpp b/src/modules/mysql/db_mysql_write.cpp index b7b94a3a3..b5686fa2f 100644 --- a/src/modules/mysql/db_mysql_write.cpp +++ b/src/modules/mysql/db_mysql_write.cpp @@ -2,8 +2,6 @@ #include "db_mysql.h" -static Module *me; - static std::string BuildFlagsList(ChannelInfo *ci) { std::string ret; @@ -80,11 +78,16 @@ static std::string MakeMLock(ChannelInfo *ci, bool status) { std::string ret; - for (int i = 0; ChannelModes[i].Mode != -1; ++i) + for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it) { - if (ci->HasMLock(ChannelModes[i].Mode, status)) + if ((*it)->Class == MC_CHANNEL) { - ret += " " + ChannelModes[i].Name; + ChannelMode *cm = dynamic_cast<ChannelMode *>(*it); + + if (ci->HasMLock(cm->Name, status)) + { + ret += " " + cm->NameAsString; + } } } @@ -108,12 +111,17 @@ static std::string GetMLockParams(ChannelInfo *ci) { std::string ret; - for (int i = 0; ChannelModes[i].Mode != -1; ++i) + for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it) { - std::string param; - if (ci->GetParam(ChannelModes[i].Mode, param)) + if ((*it)->Class == MC_CHANNEL) { - ret += " " + ChannelModes[i].Name + " " + param; + ChannelMode *cm = dynamic_cast<ChannelMode *>(*it); + + std::string param; + if (ci->GetParam(cm->Name, param)) + { + ret += " " + cm->NameAsString + " " + param; + } } } @@ -166,14 +174,14 @@ static BotInfo *CurBot = NULL; void Write(const std::string &data) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_extra` (data) VALUES(" << mysqlpp::quote << data << ")"; ExecuteQuery(query); } void WriteMetadata(const std::string &key, const std::string &data) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_metadata` (name, value) VALUES(" << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")"; ExecuteQuery(query); } @@ -183,7 +191,7 @@ void WriteNickMetadata(const std::string &key, const std::string &data) if (!CurNick) throw CoreException("WriteNickMetadata without a nick to write"); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ns_alias_metadata` (nick, name, value) VALUES(" << mysqlpp::quote << CurNick->nick << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")"; ExecuteQuery(query); } @@ -193,7 +201,7 @@ void WriteCoreMetadata(const std::string &key, const std::string &data) if (!CurCore) throw CoreException("WritCoreMetadata without a core to write"); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ns_core_metadata` (nick, name, value) VALUES(" << mysqlpp::quote << CurCore->display << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")"; ExecuteQuery(query); } @@ -203,7 +211,7 @@ void WriteChannelMetadata(const std::string &key, const std::string &data) if (!CurChannel) throw CoreException("WriteChannelMetadata without a channel to write"); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_cs_info_metadata` (channel, name, value) VALUES(" << mysqlpp::quote << CurChannel->name << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")"; ExecuteQuery(query); } @@ -213,60 +221,53 @@ void WriteBotMetadata(const std::string &key, const std::string &data) if (!CurBot) throw CoreException("WriteBotMetadata without a bot to write"); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_bs_info_metadata` (botname, name, value) VALUES(" << mysqlpp::quote << CurBot->nick << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")"; ExecuteQuery(query); } static void SaveDatabases() { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); - query << "TRUNCATE TABLE `anope_ns_core`"; - ExecuteQuery(query); query << "TRUNCATE TABLE `anope_ns_alias`"; ExecuteQuery(query); - for (int i = 0; i < 1024; ++i) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (NickAlias *na = nalists[i]; na; na = na->next) - { - me->OnNickRegister(na); - } + me->OnNickRegister(it->second); } - query << "TRUNCATE TABLE `anope_ns_access`"; + query << "TRUNCATE TABLE `anope_ns_core`"; ExecuteQuery(query); query << "TRUNCATE TABLE `anope_ms_info`"; ExecuteQuery(query); - - for (int i = 0; i < 1024; ++i) + + for (nickcore_map::const_iterator nit = NickCoreList.begin(); nit != NickCoreList.end(); ++nit) { - for (NickCore *nc = nclists[i]; nc; nc = nc->next) + NickCore *nc = nit->second; + + for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it) { - for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it) - { - query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << *it << ")"; - ExecuteQuery(query); - } + query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << *it << ")"; + ExecuteQuery(query); + } - for (unsigned j = 0; j < nc->memos.memos.size(); ++j) - { - Memo *m = nc->memos.memos[j]; + for (unsigned j = 0; j < nc->memos.memos.size(); ++j) + { + Memo *m = nc->memos.memos[j]; - me->OnMemoSend(NULL, nc, m); - } + me->OnMemoSend(NULL, nc, m); } } + query << "TRUNCATE TABLE `anope_bs_core`"; ExecuteQuery(query); - for (int i = 0; i < 256; ++i) + + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) { - for (BotInfo *bi = botlists[i]; bi; bi = bi->next) - { - me->OnBotCreate(bi); - } + me->OnBotCreate(it->second); } query << "TRUNCATE TABLE `anope_cs_info`"; @@ -280,95 +281,86 @@ static void SaveDatabases() query << "TRUNCATE TABLE `anope_cs_levels`"; ExecuteQuery(query); - for (int i = 0; i < 256; ++i) + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) { - for (ChannelInfo *ci = chanlists[i]; ci; ci = ci->next) - { - me->OnChanRegistered(ci); - - for (unsigned j = 0; j < ci->GetBadWordCount(); ++j) - { - BadWord *bw = ci->GetBadWord(j); + ChannelInfo *ci = it->second; + + me->OnChanRegistered(ci); - if (bw->InUse) - { - me->OnBadWordAdd(ci, bw); - } - } + for (unsigned j = 0; j < ci->GetBadWordCount(); ++j) + { + BadWord *bw = ci->GetBadWord(j); - for (unsigned j = 0; j < ci->GetAccessCount(); ++j) - { - ChanAccess *access = ci->GetAccess(j); + me->OnBadWordAdd(ci, bw); + } - if (access->in_use) - { - query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('" << access->level << "', " << mysqlpp::quote << access->nc->display << ", " << mysqlpp::quote << ci->name << ", " << access->last_seen << ", " << mysqlpp::quote << access->creator << ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)"; - ExecuteQuery(query); - } - } + for (unsigned j = 0; j < ci->GetAccessCount(); ++j) + { + ChanAccess *access = ci->GetAccess(j); - for (unsigned j = 0; j < ci->GetAkickCount(); ++j) - { - AutoKick *ak = ci->GetAkick(j); + query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('" << access->level << "', " << mysqlpp::quote << access->nc->display << ", " << mysqlpp::quote << ci->name << ", " << access->last_seen << ", " << mysqlpp::quote << access->creator << ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)"; + ExecuteQuery(query); + } - if (ak->InUse) - { - me->OnAkickAdd(ci, ak); - } - } + for (unsigned j = 0; j < ci->GetAkickCount(); ++j) + { + AutoKick *ak = ci->GetAkick(j); - for (int k = 0; k < CA_SIZE; ++k) - { - query << "INSERT DELAYED INTO `anope_cs_levels` (channel, position, level) VALUES(" << mysqlpp::quote << ci->name << ", '" << k << "', '" << ci->levels[k] << "') ON DUPLICATE KEY UPDATE position=VALUES(position), level=VALUES(level)"; - ExecuteQuery(query); - } + me->OnAkickAdd(NULL, ci, ak); + } + + for (int k = 0; k < CA_SIZE; ++k) + { + query << "INSERT DELAYED INTO `anope_cs_levels` (channel, position, level) VALUES(" << mysqlpp::quote << ci->name << ", '" << k << "', '" << ci->levels[k] << "') ON DUPLICATE KEY UPDATE position=VALUES(position), level=VALUES(level)"; + ExecuteQuery(query); + } - for (unsigned j = 0; j < ci->memos.memos.size(); ++j) - { - Memo *m = ci->memos.memos[j]; + for (unsigned j = 0; j < ci->memos.memos.size(); ++j) + { + Memo *m = ci->memos.memos[j]; - me->OnMemoSend(NULL, ci, m); - } + me->OnMemoSend(NULL, ci, m); } } query << "TRUNCATE TABLE `anope_ns_request`"; ExecuteQuery(query); - for (int i = 0; i < 1024; i++) + for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it) { - for (NickRequest *nr = nrlists[i]; nr; nr = nr->next) - { - me->OnMakeNickRequest(nr); - } + me->OnMakeNickRequest(it->second); } - for (int i = 0; i < akills.count; ++i) + if (SGLine) { - Akill *ak = static_cast<Akill *>(akills.list[i]); - - me->OnAddAkill(NULL, ak); + for (unsigned i = 0; i < SGLine->GetCount(); ++i) + { + me->OnAddAkill(NULL, SGLine->GetEntry(i)); + } } - for (int i = 0; i < sglines.count; ++i) + if (SZLine) { - SXLine *x = static_cast<SXLine *>(sglines.list[i]); - - me->OnAddSXLine(NULL, x, SX_SGLINE); + for (unsigned i = 0; i < SZLine->GetCount(); ++i) + { + me->OnAddXLine(NULL, SZLine->GetEntry(i), X_SZLINE); + } } - for (int i = 0; i < sqlines.count; ++i) + if (SQLine) { - SXLine *x = static_cast<SXLine *>(sqlines.list[i]); - - me->OnAddSXLine(NULL, x, SX_SQLINE); + for (unsigned i = 0; i < SQLine->GetCount(); ++i) + { + me->OnAddXLine(NULL, SQLine->GetEntry(i), X_SQLINE); + } } - for (int i = 0; i < szlines.count; ++i) + if (SNLine) { - SXLine *x = static_cast<SXLine *>(szlines.list[i]); - - me->OnAddSXLine(NULL, x, SX_SZLINE); + for (unsigned i = 0; i < SNLine->GetCount(); ++i) + { + me->OnAddXLine(NULL, SNLine->GetEntry(i), X_SNLINE); + } } for (int i = 0; i < nexceptions; ++i) @@ -382,7 +374,7 @@ static void SaveDatabases() class CommandSyncSQL : public Command { public: - CommandSyncSQL(const std::string &cname) : Command(cname, 0, 0, "operserv/sqlsync") + CommandSyncSQL(const ci::string &cname) : Command(cname, 0, 0, "operserv/sqlsync") { } @@ -399,6 +391,11 @@ class CommandSyncSQL : public Command notice_help(Config.s_OperServ, u, OPER_HELP_SYNC); return true; } + + void OnServHelp(User *u) + { + notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLSYNC); + } }; class DBMySQLWrite : public DBMySQL @@ -410,7 +407,7 @@ class DBMySQLWrite : public DBMySQL ModuleManager::Attach(I_OnServerConnect, this); - this->AddCommand(OPERSERV, new CommandSyncSQL("SQLSYNC")); + this->AddCommand(OperServ, new CommandSyncSQL("SQLSYNC")); if (uplink_server) OnServerConnect(); @@ -441,67 +438,51 @@ class DBMySQLWrite : public DBMySQL /* MemoServ */ I_OnMemoSend, I_OnMemoDel, /* OperServ */ - I_OnOperServHelp, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel, - I_OnAddSXLine, I_OnDelSXLine + I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel, + I_OnAddXLine, I_OnDelXLine }; - ModuleManager::Attach(i, this, 40); - } - - void OnOperServHelp(User *u) - { - notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLSYNC); + ModuleManager::Attach(i, this, 39); } EventReturn OnSaveDatabase() { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "TRUNCATE TABLE `anope_os_core`"; ExecuteQuery(query); query << "INSERT DELAYED INTO `anope_os_core` (maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count) VALUES("; - query << maxusercnt << ", " << maxusertime << ", " << akills.count << ", " << sqlines.count << ", " << sglines.count << ", " << szlines.count << ")"; + query << maxusercnt << ", " << maxusertime << ", " << (SGLine ? SGLine->GetCount() : 0) << ", " << (SQLine ? SQLine->GetCount() : 0) << ", " << (SNLine ? SNLine->GetCount() : 0) << ", " << (SZLine ? SZLine->GetCount() : 0) << ")"; ExecuteQuery(query); - for (int i = 0; i < 1024; ++i) + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (NickCore *nc = nclists[i]; nc; nc = nc->next) - { - CurCore = nc; - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteCoreMetadata, nc)); - } + CurCore = it->second; + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteCoreMetadata, CurCore)); } - for (int i = 0; i < 1024; ++i) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (NickAlias *na = nalists[i]; na; na = na->next) - { - CurNick = na; - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteNickMetadata, na)); - } + CurNick = it->second; + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteNickMetadata, CurNick)); } - for (int i = 0; i < 256; ++i) + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) { - for (ChannelInfo *ci = chanlists[i]; ci; ci = ci->next) - { - CurChannel = ci; - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteChannelMetadata, ci)); - } + CurChannel = it->second; + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteChannelMetadata, CurChannel)); } - for (int i = 0; i < 256; ++i) + for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it) { - for (BotInfo *bi = botlists[i]; bi; bi = bi->next) - { - CurBot = bi; - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteBotMetadata, bi)); - /* This is for the core bots, bots added by users are already handled by an event */ - query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES("; - query << mysqlpp::quote << bi->nick << ", " << mysqlpp::quote << bi->user << ", " << mysqlpp::quote << bi->host; - query << ", " << mysqlpp::quote << bi->real << ", '" << GetBotServFlags(bi) << "', " << bi->created << ", "; - query << bi->chancount << ") ON DUPLICATE KEY UPDATE nick=VALUES(nick), user=VALUES(user), host=VALUES(host), rname=VALUES(rname), flags=VALUES(flags), created=VALUES(created), chancount=VALUES(created)"; - ExecuteQuery(query); - } + CurBot = it->second; + FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteBotMetadata, CurBot)); + + /* This is for the core bots, bots added by users are already handled by an event */ + query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES("; + query << mysqlpp::quote << CurBot->nick << ", " << mysqlpp::quote << CurBot->user << ", " << mysqlpp::quote << CurBot->host; + query << ", " << mysqlpp::quote << CurBot->real << ", '" << GetBotServFlags(CurBot) << "', " << CurBot->created << ", "; + query << CurBot->chancount << ") ON DUPLICATE KEY UPDATE nick=VALUES(nick), user=VALUES(user), host=VALUES(host), rname=VALUES(rname), flags=VALUES(flags), created=VALUES(created), chancount=VALUES(created)"; + ExecuteQuery(query); } FOREACH_MOD(I_OnDatabaseWrite, OnDatabaseWrite(Write)); @@ -511,14 +492,14 @@ class DBMySQLWrite : public DBMySQL void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); if (service == Config.s_NickServ) { if (u->Account() && ((command == "SET" && !params.empty()) || (command == "SASET" && u->Account()->HasCommand("nickserv/saset") && params.size() > 1))) { ci::string cmd = (command == "SET" ? params[0] : params[1]); - NickCore *nc = (command == "SET" ? u->Account() : findcore(params[0].c_str())); + NickCore *nc = (command == "SET" ? u->Account() : findcore(params[0])); if (!nc) return; if (cmd == "PASSWORD" && params.size() > 1) @@ -562,7 +543,7 @@ class DBMySQLWrite : public DBMySQL { if (command == "SET" && u->Account() && params.size() > 1) { - ChannelInfo *ci = cs_findchan(params[0].c_str()); + ChannelInfo *ci = cs_findchan(params[0]); if (!ci) return; if (!u->Account()->HasPriv("chanserv/set") && check_access(u, ci, CA_SET)) @@ -622,7 +603,7 @@ class DBMySQLWrite : public DBMySQL { if (command == "KICK" && params.size() > 2) { - ChannelInfo *ci = cs_findchan(params[0].c_str()); + ChannelInfo *ci = cs_findchan(params[0]); if (!ci) return; if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) @@ -660,12 +641,12 @@ class DBMySQLWrite : public DBMySQL } else if (command == "SET" && params.size() > 2) { - ChannelInfo *ci = cs_findchan(params[0].c_str()); + ChannelInfo *ci = cs_findchan(params[0]); if (ci && !check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration")) return; BotInfo *bi = NULL; if (!ci) - bi = findbot(params[0].c_str()); + bi = findbot(params[0]); if (bi && params[1] == "PRIVATE" && u->Account()->HasPriv("botserv/set/private")) { query << "UPDATE `anope_bs_core` SET `flags` = '" << GetBotServFlags(bi) << "' WHERE `nick` = " << mysqlpp::quote << bi->nick; @@ -685,28 +666,28 @@ class DBMySQLWrite : public DBMySQL void OnNickAddAccess(NickCore *nc, const std::string &entry) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << entry << ")"; ExecuteQuery(query); } void OnNickEraseAccess(NickCore *nc, const std::string &entry) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_ns_access` WHERE `display` = " << mysqlpp::quote << nc->display << " AND `access` = " << mysqlpp::quote << entry; ExecuteQuery(query); } void OnNickClearAccess(NickCore *nc) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_ns_access` WHERE `display` = " << mysqlpp::quote << nc->display; ExecuteQuery(query); } void OnDelCore(NickCore *nc) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_cs_access` WHERE `display` = " << mysqlpp::quote << nc->display; ExecuteQuery(query); query << "DELETE FROM `anope_cs_akick` WHERE `mask` = " << mysqlpp::quote << nc->display; @@ -724,7 +705,7 @@ class DBMySQLWrite : public DBMySQL void OnNickForbidden(NickAlias *na) { std::string flags = BuildFlagsList(na); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_ns_alias` SET `flags` = '" << (!flags.empty() ? flags : "") << "' WHERE `nick` = " << mysqlpp::quote << na->nick; ExecuteQuery(query); } @@ -736,7 +717,7 @@ class DBMySQLWrite : public DBMySQL void OnMakeNickRequest(NickRequest *nr) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ns_request` (nick, passcode, password, email, requested) VALUES(" << mysqlpp::quote << nr->nick << ", "; query << mysqlpp::quote << nr->passcode << ", " << mysqlpp::quote << nr->password << ", " << mysqlpp::quote << nr->email << ", '"; query << nr->requested << "')"; @@ -745,7 +726,7 @@ class DBMySQLWrite : public DBMySQL void OnDelNickRequest(NickRequest *nr) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_ns_request` WHERE `nick` = " << mysqlpp::quote << nr->nick; ExecuteQuery(query); } @@ -753,7 +734,7 @@ class DBMySQLWrite : public DBMySQL void OnNickRegister(NickAlias *na) { std::string flags = BuildFlagsList(na); - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ns_alias` (nick, last_quit, last_realname, last_usermask, time_registered, last_seen, flags, display) VALUES("; query << mysqlpp::quote << na->nick << ", " << mysqlpp::quote << (na->last_quit ? na->last_quit : "") << ", "; query << mysqlpp::quote << (na->last_realname ? na->last_realname : "") << ", "; @@ -776,7 +757,7 @@ class DBMySQLWrite : public DBMySQL void OnChangeCoreDisplay(NickCore *nc, const std::string &newdisplay) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_ns_core` SET `display` = " << mysqlpp::quote << newdisplay << " WHERE `display` = " << mysqlpp::quote << nc->display; ExecuteQuery(query); query << "UPDATE `anope_ns_alias` SET `display` = " << mysqlpp::quote << newdisplay << " WHERE `display` = " << mysqlpp::quote << nc->display; @@ -795,42 +776,42 @@ class DBMySQLWrite : public DBMySQL void OnNickSuspend(NickAlias *na) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_ns_core` SET `flags` = '" << BuildFlagsList(na->nc) << "' WHERE `display` = " << mysqlpp::quote << na->nc->display; ExecuteQuery(query); } void OnAccessAdd(ChannelInfo *ci, User *u, NickAlias *na, int level) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" << level << ", " << mysqlpp::quote << na->nc->display << ", " << mysqlpp::quote << ci->name << ", " << time(NULL) << ", " << mysqlpp::quote << u->nick << ")"; ExecuteQuery(query); } void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_cs_access` WHERE `display` = " << mysqlpp::quote << nc->display << " AND `channel` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); } void OnAccessChange(ChannelInfo *ci, User *u, NickAlias *na, int level) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" << level << ", " << mysqlpp::quote << na->nc->display << ", " << mysqlpp::quote << ci->name << ", " << time(NULL) << ", " << mysqlpp::quote << u->nick << ") ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)"; ExecuteQuery(query); } void OnAccessClear(ChannelInfo *ci, User *u) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_cs_access` WHERE `channel` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); } void OnLevelChange(User *u, ChannelInfo *ci, int pos, int what) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); if (pos >= 0) { @@ -849,7 +830,7 @@ class DBMySQLWrite : public DBMySQL void OnChanForbidden(ChannelInfo *ci) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_cs_info` (name, time_registered, last_used, flags, forbidby, forbidreason) VALUES ("; query << mysqlpp::quote << ci->name << ", " << ci->time_registered << ", " << ci->last_used << ", '" << BuildFlagsList(ci) << "', " << mysqlpp::quote << ci->forbidby << ", " << mysqlpp::quote << ci->forbidreason << ")"; ExecuteQuery(query); @@ -857,7 +838,7 @@ class DBMySQLWrite : public DBMySQL void OnDelChan(ChannelInfo *ci) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_cs_access` WHERE `channel` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); query << "DELETE FROM `anope_cs_akick` WHERE `channel` = " << mysqlpp::quote << ci->name; @@ -874,7 +855,7 @@ class DBMySQLWrite : public DBMySQL void OnChanRegistered(ChannelInfo *ci) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); std::string flags = BuildFlagsList(ci), mlockon = GetMLockOn(ci), mlockoff = GetMLockOff(ci), mlockparams = GetMLockParams(ci); query << "INSERT DELAYED INTO `anope_cs_info` (name, founder, successor, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, last_topic_time, flags, forbidby, forbidreason, bantype, mlock_on, mlock_off, mlock_params, entry_message, memomax, botnick, botflags, capsmin, capspercent, floodlines, floodsecs, repeattimes) VALUES("; query << mysqlpp::quote << ci->name << ", " << mysqlpp::quote << (ci->founder ? ci->founder->display : "") << ", "; @@ -895,7 +876,7 @@ class DBMySQLWrite : public DBMySQL void OnChanSuspend(ChannelInfo *ci) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_cs_info` SET `flags` = '" << BuildFlagsList(ci) << "' WHERE `name` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); query << "UPDATE `anope_cs_info` SET `forbidby` = " << mysqlpp::quote << ci->forbidby << " WHERE `name` = " << mysqlpp::quote << ci->name; @@ -906,7 +887,7 @@ class DBMySQLWrite : public DBMySQL void OnAkickAdd(ChannelInfo *ci, AutoKick *ak) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_cs_akick` (channel, flags, mask, reason, creator, created, last_used) VALUES("; query << mysqlpp::quote << ci->name << ", '"; if (ak->HasFlag(AK_ISNICK)) @@ -921,14 +902,14 @@ class DBMySQLWrite : public DBMySQL void OnAkickDel(ChannelInfo *ci, AutoKick *ak) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_cs_akick` WHERE `channel`= " << mysqlpp::quote << ci->name << " AND `mask` = " << mysqlpp::quote << (ak->HasFlag(AK_ISNICK) ? ak->nc->display : ak->mask); ExecuteQuery(query); } void OnBotCreate(BotInfo *bi) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES("; query << mysqlpp::quote << bi->nick << ", " << mysqlpp::quote << bi->user << ", " << mysqlpp::quote << bi->host << ", "; query << mysqlpp::quote << bi->real << ", '" << GetBotServFlags(bi) << "', " << bi->created << ", " << bi->chancount << ") "; @@ -943,7 +924,7 @@ class DBMySQLWrite : public DBMySQL void OnBotDelete(BotInfo *bi) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_bs_core` WHERE `nick` = " << mysqlpp::quote << bi->nick; ExecuteQuery(query); query << "UPDATE `anope_cs_info` SET `botnick` = '' WHERE `botnick` = " << mysqlpp::quote << bi->nick; @@ -952,7 +933,7 @@ class DBMySQLWrite : public DBMySQL EventReturn OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_cs_info` SET `botnick` = " << mysqlpp::quote << bi->nick << " WHERE `name` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); return EVENT_CONTINUE; @@ -960,7 +941,7 @@ class DBMySQLWrite : public DBMySQL EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "UPDATE `anope_cs_info` SET `botnick` = '' WHERE `name` = " << mysqlpp::quote << ci->name; ExecuteQuery(query); return EVENT_CONTINUE; @@ -968,7 +949,7 @@ class DBMySQLWrite : public DBMySQL void OnBadWordAdd(ChannelInfo *ci, BadWord *bw) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_bs_badwords` (channel, word, type) VALUES(" << mysqlpp::quote << ci->name << ", " << mysqlpp::quote << bw->word << ", '"; switch (bw->type) { @@ -990,7 +971,7 @@ class DBMySQLWrite : public DBMySQL void OnBadWordDel(ChannelInfo *ci, BadWord *bw) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_bs_badwords` WHERE `channel` = " << mysqlpp::quote << ci->name << " AND `word` = " << mysqlpp::quote << bw->word << " AND `type` = '"; switch (bw->type) { @@ -1012,7 +993,7 @@ class DBMySQLWrite : public DBMySQL void OnMemoSend(User *, NickCore *nc, Memo *m) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ms_info` (receiver, number, flags, time, sender, text, serv) VALUES("; query << mysqlpp::quote << nc->display << ", " << m->number << ", '" << BuildFlagsList(m) << "', " << m->time << ", "; query << mysqlpp::quote << m->sender << ", " << mysqlpp::quote << m->text << ", 'NICK')"; @@ -1021,7 +1002,7 @@ class DBMySQLWrite : public DBMySQL void OnMemoSend(User *, ChannelInfo *ci, Memo *m) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_ms_info` (receiver, number, flags, time, sender, text, serv) VALUES("; query << mysqlpp::quote << ci->name << ", " << m->number << ", '" << BuildFlagsList(m) << "', " << m->time << ", "; query << mysqlpp::quote << m->sender << ", " << mysqlpp::quote << m->text << ", 'CHAN')"; @@ -1030,7 +1011,7 @@ class DBMySQLWrite : public DBMySQL void OnMemoDel(NickCore *nc, MemoInfo *mi, int number) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); if (number) query << "DELETE FROM `anope_ms_info` WHERE `receiver` = " << mysqlpp::quote << nc->display << " AND `number` = " << number; else @@ -1040,7 +1021,7 @@ class DBMySQLWrite : public DBMySQL void OnMemoDel(ChannelInfo *ci, MemoInfo *mi, int number) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); if (number) query << "DELETE FROM `anope_ms_info` WHERE `receiver` = " << mysqlpp::quote << ci->name << " AND `number` = " << number; else @@ -1048,21 +1029,21 @@ class DBMySQLWrite : public DBMySQL ExecuteQuery(query); } - EventReturn OnAddAkill(User *, Akill *ak) + EventReturn OnAddAkill(User *, XLine *ak) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES("; - query << mysqlpp::quote << ak->user << ", " << mysqlpp::quote << ak->host << ", " << mysqlpp::quote << ak->by; - query << ", " << mysqlpp::quote << ak->reason << ", " << ak->seton << ", " << ak->expires << ")"; + query << mysqlpp::quote << ak->GetUser().c_str() << ", " << mysqlpp::quote << ak->GetHost().c_str() << ", " << mysqlpp::quote << ak->By.c_str(); + query << ", " << mysqlpp::quote << ak->Reason << ", " << ak->Created << ", " << ak->Expires << ")"; ExecuteQuery(query); return EVENT_CONTINUE; } - void OnDelAkill(User *, Akill *ak) + void OnDelAkill(User *, XLine *ak) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); if (ak) - query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->host; + query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->GetHost().c_str(); else query << "TRUNCATE TABLE `anope_os_akills`"; ExecuteQuery(query); @@ -1070,7 +1051,7 @@ class DBMySQLWrite : public DBMySQL EventReturn OnExceptionAdd(User *, Exception *ex) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_os_exceptions` (mask, slimit, who, reason, time, expires) VALUES("; query << mysqlpp::quote << ex->mask << ", " << ex->limit << ", " << mysqlpp::quote << ex->who << ", "; query << mysqlpp::quote << ex->reason << ", " << ex->time << ", " << ex->expires << ")"; @@ -1080,32 +1061,32 @@ class DBMySQLWrite : public DBMySQL void OnExceptionDel(User *, Exception *ex) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "DELETE FROM `anope_os_exceptions` WHERE `mask` = " << mysqlpp::quote << ex->mask; ExecuteQuery(query); } - EventReturn OnAddSXLine(User *, SXLine *sx, SXLineType Type) + EventReturn OnAddXLine(User *, XLine *x, XLineType Type) { - mysqlpp::Query query(Me->Con); + mysqlpp::Query query(me->Con); query << "INSERT DELAYED INTO `anope_os_sxlines` (type, mask, xby, reason, seton, expire) VALUES('"; - query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "', "; - query << mysqlpp::quote << sx->mask << ", " << mysqlpp::quote << sx->by << ", " << mysqlpp::quote << sx->reason; - query << ", " << sx->seton << ", " << sx->expires << ")"; + query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "', "; + query << mysqlpp::quote << x->Mask.c_str() << ", " << mysqlpp::quote << x->By.c_str() << ", " << mysqlpp::quote << x->Reason; + query << ", " << x->Created << ", " << x->Expires << ")"; ExecuteQuery(query); return EVENT_CONTINUE; } - void OnDelSXLine(User *, SXLine *sx, SXLineType Type) + void OnDelXLine(User *, XLine *x, XLineType Type) { - mysqlpp::Query query(Me->Con); - if (sx) + mysqlpp::Query query(me->Con); + if (x) { - query << "DELETE FROM `anope_os_sxlines` WHERE `mask` = " << mysqlpp::quote << sx->mask << " AND `type` = '"; - query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'"; + query << "DELETE FROM `anope_os_xlines` WHERE `mask` = " << mysqlpp::quote << x->Mask.c_str() << " AND `type` = '"; + query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'"; } else - query << "DELETE FROM `anope_os_sxlines` WHERE `type` = '" << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'"; + query << "DELETE FROM `anope_os_xlines` WHERE `type` = '" << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'"; ExecuteQuery(query); } }; diff --git a/src/modules/ns_maxemail.c b/src/modules/ns_maxemail.cpp index e98dc62d7..2399dba68 100644 --- a/src/modules/ns_maxemail.c +++ b/src/modules/ns_maxemail.cpp @@ -127,20 +127,17 @@ class NSMaxEmail : public Module int count_email_in_use(const char *email, User * u) { - NickCore *nc; - int i; int count = 0; if (!email) return 0; - for (i = 0; i < 1024; ++i) + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (nc = nclists[i]; nc; nc = nc->next) - { - if (!(u->Account() && u->Account() == nc) && nc->email && !stricmp(nc->email, email)) - ++count; - } + NickCore *nc = it->second; + + if (!(u->Account() && u->Account() == nc) && nc->email && !stricmp(nc->email, email)) + ++count; } return count; diff --git a/src/modules/os_info.c b/src/modules/os_info.cpp index 87d8ea298..38d9c99c5 100644 --- a/src/modules/os_info.c +++ b/src/modules/os_info.cpp @@ -116,6 +116,11 @@ class CommandNSOInfo : public Command { me->NoticeLang(Config.s_NickServ, u, OINFO_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_NickServ, u, OINFO_HELP_CMD); + } }; class CommandCSOInfo : public Command @@ -180,6 +185,11 @@ class CommandCSOInfo : public Command { me->NoticeLang(Config.s_ChanServ, u, OCINFO_SYNTAX); } + + void OnServHelp(User *u) + { + me->NoticeLang(Config.s_ChanServ, u, OCINFO_HELP_CMD); + } }; class OSInfo : public Module @@ -193,8 +203,8 @@ class OSInfo : public Module this->SetVersion(VERSION); this->SetType(SUPPORTED); - this->AddCommand(NICKSERV, new CommandNSOInfo()); - this->AddCommand(CHANSERV, new CommandCSOInfo()); + this->AddCommand(NickServ, new CommandNSOInfo()); + this->AddCommand(ChanServ, new CommandCSOInfo()); const char* langtable_en_us[] = { /* OINFO_SYNTAX */ @@ -409,83 +419,47 @@ class OSInfo : public Module this->InsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru); this->InsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it); - Implementation i[] = { I_OnNickServHelp, I_OnChanServHelp, I_OnPostCommand, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata }; - ModuleManager::Attach(i, this, 5); + Implementation i[] = { I_OnNickInfo, I_OnChanInfo, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata }; + ModuleManager::Attach(i, this, 4); } ~OSInfo() { - int i; - NickCore *nc; - ChannelInfo *ci; - OnSaveDatabase(); - for (i = 0; i < 1024; ++i) + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - /* Remove the nick Cores */ - for (nc = nclists[i]; nc; nc = nc->next) - { - nc->Shrink("os_info"); - } + NickCore *nc = it->second; + + nc->Shrink("os_info"); } - for (i = 0; i < 256; ++i) + for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) { - for (ci = chanlists[i]; ci; ci = ci->next) - { - ci->Shrink("os_info"); - } + ChannelInfo *ci = it->second; + + ci->Shrink("os_info"); } } - void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) + void OnNickInfo(User *u, NickAlias *na, bool) { - if (command == "INFO") + if (is_oper(u)) { - if (service == Config.s_NickServ) - { - const char *nick = params[0].c_str(); - NickAlias *na = NULL; - - if (is_oper(u)) /* Only show our goodies to opers */ - { - if ((na = findnick(nick))) /* ok we've found the user */ - { - /* If we have any info on this user */ - char *c; - if (na->nc->GetExtArray("os_info", c)) - u->SendMessage(Config.s_NickServ, " OperInfo: %s", c); - } - } - } - else if (service == Config.s_ChanServ) - { - const char *chan = params[0].c_str(); - ChannelInfo *ci = NULL; - - if (is_oper(u)) /* Only show our goodies to opers */ - { - if ((ci = cs_findchan(chan))) - { - /* If we have any info on this channel */ - char *c; - if (ci->GetExtArray("os_info", c)) - u->SendMessage(Config.s_ChanServ, " OperInfo: %s", c); - } - } - } + char *c; + if (na->nc->GetExtArray("os_info", c)) + u->SendMessage(Config.s_NickServ, " OperInfo: %s", c); } } - void OnNickServHelp(User *u) - { - this->NoticeLang(Config.s_NickServ, u, OINFO_HELP_CMD); - } - - void OnChanServHelp(User *u) + void OnChanInfo(User *u, ChannelInfo *ci, bool) { - this->NoticeLang(Config.s_ChanServ, u, OCINFO_HELP_CMD); + if (is_oper(u)) + { + char *c; + if (ci->GetExtArray("os_info", c)) + u->SendMessage(Config.s_ChanServ, " OperInfo: %s", c); + } } void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), NickCore *nc) diff --git a/src/modules/ssl/m_ssl.cpp b/src/modules/ssl/m_ssl.cpp new file mode 100644 index 000000000..be3e5da1f --- /dev/null +++ b/src/modules/ssl/m_ssl.cpp @@ -0,0 +1,148 @@ +/* RequiredLibraries: ssl,crypt */ + +#include "module.h" + +#include <openssl/bio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/crypto.h> +#include <openssl/evp.h> + +#define CERTFILE "anope.cert" +#define KEYFILE "anope.key" + +static SSL_CTX *ctx; + +class SSLSocket : public Socket +{ + private: + SSL *sslsock; + + int RecvInternal(char *buf, size_t sz) const + { + return SSL_read(sslsock, buf, sz); + } + + int SendInternal(const std::string &buf) const + { + return SSL_write(sslsock, buf.c_str(), buf.size()); + } + public: + SSLSocket(const std::string &nTargetHost, int nPort, const std::string &nBindHost = "", bool nIPv6 = false) : Socket(nTargetHost, nPort, nBindHost, nIPv6) + { + sslsock = SSL_new(ctx); + + if (!sslsock) + throw CoreException("Unable to initialize SSL socket"); + + SSL_set_connect_state(sslsock); + SSL_set_fd(sslsock, Sock); + SSL_connect(sslsock); + + UplinkSock = this; + } + + ~SSLSocket() + { + SSL_shutdown(sslsock); + SSL_free(sslsock); + + UplinkSock = NULL; + } + + bool Read(const std::string &buf) + { + process(buf); + return true; + } +}; + +class SSLModule : public Module +{ + public: + SSLModule(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(SUPPORTED); + this->SetPermanent(true); + + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + + ctx = SSL_CTX_new(SSLv23_client_method()); + + if (!ctx) + { + throw ModuleException("Error initializing SSL CTX"); + } + + if (IsFile(CERTFILE)) + { + if (!SSL_CTX_use_certificate_file(ctx, CERTFILE, SSL_FILETYPE_PEM)) + { + SSL_CTX_free(ctx); + throw ModuleException("Error loading certificate"); + } + } + else + { + Alog() << "m_ssl: No certificate file found"; + } + + if (IsFile(KEYFILE)) + { + if (!SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM)) + { + SSL_CTX_free(ctx); + throw ModuleException("Error loading private key"); + } + } + else + { + if (IsFile(CERTFILE)) + { + SSL_CTX_free(ctx); + throw ModuleException("Error loading private key - file not found"); + } + else + { + Alog() << "m_ssl: No private key found"; + } + } + + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); + SSL_CTX_set_options(ctx, SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_ALL); + + ModuleManager::Attach(I_OnPreServerConnect, this); + } + + ~SSLModule() + { + SSL_CTX_free(ctx); + } + + EventReturn OnPreServerConnect(Uplink *u, int Number) + { + ConfigReader config; + + if (config.ReadFlag("uplink", "ssl", "no", Number - 1)) + { + try + { + new SSLSocket(u->host, u->port, Config.LocalHost ? Config.LocalHost : "", u->ipv6); + Alog() << "Connected to Server " << Number << " (" << u->host << ":" << u->port << ")"; + } + catch (SocketException& ex) + { + Alog() << "Unable to connect with SSL to server" << Number << " (" << u->host << ":" << u->port << "), " << ex.GetReason(); + } + + return EVENT_ALLOW; + } + + return EVENT_CONTINUE; + } +}; + +MODULE_INIT(SSLModule) diff --git a/src/nickalias.cpp b/src/nickalias.cpp index afd40ccd7..a196145b9 100644 --- a/src/nickalias.cpp +++ b/src/nickalias.cpp @@ -1,31 +1,24 @@ #include "services.h" #include "modules.h" -#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31)) - NickRequest::NickRequest(const std::string &nickname) { if (nickname.empty()) throw CoreException("Empty nick passed to NickRequest constructor"); - next = prev = NULL; email = NULL; requested = lastmail = 0; this->nick = sstrdup(nickname.c_str()); - insert_requestnick(this); // till this is destroyed / redone in STL + + NickRequestList[this->nick] = this; } NickRequest::~NickRequest() { FOREACH_MOD(I_OnDelNickRequest, OnDelNickRequest(this)); - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - nrlists[HASH(this->nick)] = this->next; + NickRequestList.erase(this->nick); if (this->nick) delete [] this->nick; @@ -44,14 +37,14 @@ NickAlias::NickAlias(const std::string &nickname, NickCore *nickcore) else if (!nickcore) throw CoreException("Empty nickcore passed to NickAlias constructor"); - next = prev = NULL; nick = last_quit = last_realname = last_usermask = NULL; time_registered = last_seen = 0; this->nick = sstrdup(nickname.c_str()); this->nc = nickcore; - slist_add(&nc->aliases, this); - alpha_insert_alias(this); + nc->aliases.push_back(this); + + NickAliasList[this->nick] = this; for (std::list<std::pair<std::string, std::string> >::iterator it = Config.Opers.begin(); it != Config.Opers.end(); it++) { @@ -95,8 +88,12 @@ NickAlias::~NickAlias() if (this->nc) { /* Next: see if our core is still useful. */ - slist_remove(&this->nc->aliases, this); - if (this->nc->aliases.count == 0) + std::list<NickAlias *>::iterator it = std::find(this->nc->aliases.begin(), this->nc->aliases.end(), this); + if (it != this->nc->aliases.end()) + { + nc->aliases.erase(it); + } + if (this->nc->aliases.empty()) { delete this->nc; this->nc = NULL; @@ -110,12 +107,7 @@ NickAlias::~NickAlias() } /* Remove us from the aliases list */ - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - nalists[HASH(this->nick)] = this->next; + NickAliasList.erase(this->nick); delete [] this->nick; if (this->last_usermask) diff --git a/src/nickcore.cpp b/src/nickcore.cpp index 1b01c3d54..cf92b0b3d 100644 --- a/src/nickcore.cpp +++ b/src/nickcore.cpp @@ -1,7 +1,5 @@ #include "services.h" -#include "pseudo.h" - -#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31)) +#include "modules.h" /** Default constructor * @param display The display nick @@ -11,7 +9,6 @@ NickCore::NickCore(const std::string &coredisplay) if (coredisplay.empty()) throw CoreException("Empty display passed to NickCore constructor"); - next = prev = NULL; display = email = greet = url = NULL; ot = NULL; icq = 0; @@ -19,13 +16,13 @@ NickCore::NickCore(const std::string &coredisplay) lastmail = 0; this->display = sstrdup(coredisplay.c_str()); - slist_init(&this->aliases); - insert_core(this); // till hashing is redone.. /* Set default nick core flags */ for (size_t t = NI_BEGIN + 1; t != NI_END; ++t) if (Config.NSDefFlags.HasFlag(static_cast<NickCoreFlag>(t))) SetFlag(static_cast<NickCoreFlag>(t)); + + NickCoreList[this->display] = this; } /** Default destructor @@ -51,12 +48,7 @@ NickCore::~NickCore() cs_remove_nick(this); /* Remove the core from the list */ - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - nclists[HASH(this->display)] = this->next; + NickCoreList.erase(this->display); /* Log .. */ Alog() << Config.s_NickServ << ": deleting nickname group " << this->display; diff --git a/src/nickserv.c b/src/nickserv.cpp index fc6627109..c14de6ae6 100644 --- a/src/nickserv.c +++ b/src/nickserv.cpp @@ -13,15 +13,12 @@ */ #include "services.h" -#include "pseudo.h" +#include "modules.h" +#include "language.h" -/*************************************************************************/ - -#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31)) - -NickAlias *nalists[1024]; -NickCore *nclists[1024]; -NickRequest *nrlists[1024]; +nickalias_map NickAliasList; +nickcore_map NickCoreList; +nickrequest_map NickRequestList; static std::map<std::string, NickServCollide *> NickServCollides; static std::map<std::string, NickServRelease *> NickServReleases; @@ -93,24 +90,21 @@ void moduleAddNickServCmds() void get_aliases_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - int i; - NickAlias *na; - for (i = 0; i < 1024; i++) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it) { - for (na = nalists[i]; na; na = na->next) - { - count++; - mem += sizeof(*na); - if (na->nick) - mem += strlen(na->nick) + 1; - if (na->last_usermask) - mem += strlen(na->last_usermask) + 1; - if (na->last_realname) - mem += strlen(na->last_realname) + 1; - if (na->last_quit) - mem += strlen(na->last_quit) + 1; - } + NickAlias *na = it->second; + + count++; + mem += sizeof(*na); + if (na->nick) + mem += strlen(na->nick) + 1; + if (na->last_usermask) + mem += strlen(na->last_usermask) + 1; + if (na->last_realname) + mem += strlen(na->last_realname) + 1; + if (na->last_quit) + mem += strlen(na->last_quit) + 1; } *nrec = count; *memuse = mem; @@ -123,40 +117,38 @@ void get_aliases_stats(long *nrec, long *memuse) void get_core_stats(long *nrec, long *memuse) { long count = 0, mem = 0; - unsigned i, j; - NickCore *nc; + unsigned j; - for (i = 0; i < 1024; i++) + for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it) { - for (nc = nclists[i]; nc; nc = nc->next) + NickCore *nc = it->second; + + count++; + mem += sizeof(*nc); + + if (nc->display) + mem += strlen(nc->display) + 1; + if (!nc->pass.empty()) + mem += (nc->pass.capacity() + (2 * sizeof(size_t)) + (2 * sizeof(void*))); + if (nc->url) + mem += strlen(nc->url) + 1; + if (nc->email) + mem += strlen(nc->email) + 1; + if (nc->greet) + mem += strlen(nc->greet) + 1; + + mem += sizeof(std::string) * nc->access.size(); + for (j = 0; j < nc->access.size(); ++j) + mem += nc->GetAccess(j).length() + 1; + + mem += nc->memos.memos.size() * sizeof(Memo); + for (j = 0; j < nc->memos.memos.size(); j++) { - count++; - mem += sizeof(*nc); - - if (nc->display) - mem += strlen(nc->display) + 1; - if (!nc->pass.empty()) - mem += (nc->pass.capacity() + (2 * sizeof(size_t)) + (2 * sizeof(void*))); - if (nc->url) - mem += strlen(nc->url) + 1; - if (nc->email) - mem += strlen(nc->email) + 1; - if (nc->greet) - mem += strlen(nc->greet) + 1; - - mem += sizeof(std::string) * nc->access.size(); - for (j = 0; j < nc->access.size(); ++j) - mem += nc->GetAccess(j).length() + 1; - - mem += nc->memos.memos.size() * sizeof(Memo); - for (j = 0; j < nc->memos.memos.size(); j++) - { - if (nc->memos.memos[j]->text) - mem += strlen(nc->memos.memos[j]->text) + 1; - } - - mem += sizeof(void *) * nc->aliases.count; + if (nc->memos.memos[j]->text) + mem += strlen(nc->memos.memos[j]->text) + 1; } + + mem += sizeof(NickAlias *) * nc->aliases.size(); } *nrec = count; *memuse = mem; @@ -176,27 +168,21 @@ void ns_init() /* Main NickServ routine. */ -void nickserv(User * u, char *buf) +void nickserv(User *u, const std::string &buf) { - const char *cmd, *s; - - cmd = strtok(buf, " "); - - if (!cmd) - { + if (!u || buf.empty()) return; - } - else if (stricmp(cmd, "\1PING") == 0) + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') { - if (!(s = strtok(NULL, ""))) - { - s = ""; - } - ircdproto->SendCTCP(findbot(Config.s_NickServ), u->nick.c_str(), "PING %s", s); + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(NickServ, u->nick.c_str(), "%s", command.c_str()); } else { - mod_run_cmd(Config.s_NickServ, u, NICKSERV, cmd); + mod_run_cmd(NickServ, u, buf); } } @@ -216,7 +202,7 @@ int validate_user(User * u) NickAlias *na; NickRequest *nr; - if ((nr = findrequestnick(u->nick.c_str()))) + if ((nr = findrequestnick(u->nick))) { notice_lang(Config.s_NickServ, u, NICK_IS_PREREG); return 0; @@ -293,138 +279,111 @@ int validate_user(User * u) void expire_nicks() { - int i; - NickAlias *na, *next; time_t now = time(NULL); - char *tmpnick; - for (i = 0; i < 1024; i++) + for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end();) { - for (na = nalists[i]; na; na = next) + NickAlias *na = it->second; + ++it; + + User *u = finduser(na->nick); + if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified() : u->IsRecognized())) { - next = na->next; + Alog(LOG_DEBUG_2) << "NickServ: updating last seen time for " << na->nick; + na->last_seen = now; + continue; + } - User *u = finduser(na->nick); - if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified() : u->IsRecognized())) - { - Alog(LOG_DEBUG_2) << "NickServ: updating last seen time for " << na->nick; - na->last_seen = now; + if (Config.NSExpire && now - na->last_seen >= Config.NSExpire + && !na->HasFlag(NS_FORBIDDEN) && !na->HasFlag(NS_NO_EXPIRE) + && !na->nc->HasFlag(NI_SUSPENDED)) + { + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreNickExpire, OnPreNickExpire(na)); + if (MOD_RESULT == EVENT_STOP) continue; - } - - if (Config.NSExpire && now - na->last_seen >= Config.NSExpire - && !na->HasFlag(NS_FORBIDDEN) && !na->HasFlag(NS_NO_EXPIRE) - && !na->nc->HasFlag(NI_SUSPENDED)) - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreNickExpire, OnPreNickExpire(na)); - if (MOD_RESULT == EVENT_STOP) - continue; - Alog() << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " - << (na->nc->email ? na->nc->email : "none") << ")"; - tmpnick = sstrdup(na->nick); - delete na; - FOREACH_MOD(I_OnNickExpire, OnNickExpire(tmpnick)); - delete [] tmpnick; - } + Alog() << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " + << (na->nc->email ? na->nc->email : "none") << ")"; + FOREACH_MOD(I_OnNickExpire, OnNickExpire(na)); + delete na; } } } void expire_requests() { - int i; - NickRequest *nr, *next; time_t now = time(NULL); - for (i = 0; i < 1024; i++) + + for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it) { - for (nr = nrlists[i]; nr; nr = next) + NickRequest *nr = it->second; + + if (Config.NSRExpire && now - nr->requested >= Config.NSRExpire) { - next = nr->next; - if (Config.NSRExpire && now - nr->requested >= Config.NSRExpire) - { - Alog() << "Request for nick " << nr->nick << " expiring"; - delete nr; - } + Alog() << "Request for nick " << nr->nick << " expiring"; + delete nr; } } } /*************************************************************************/ -/*************************************************************************/ -/* Return the NickRequest structire for the given nick, or NULL */ NickRequest *findrequestnick(const char *nick) { - NickRequest *nr; + return findrequestnick(ci::string(nick)); +} - if (!*nick || !nick) - { - Alog(LOG_DEBUG) << "findrequestnick() called with NULL values"; - return NULL; - } +NickRequest *findrequestnick(const std::string &nick) +{ + return findrequestnick(ci::string(nick.c_str())); +} - for (nr = nrlists[HASH(nick)]; nr; nr = nr->next) - { - if (stricmp(nr->nick, nick) == 0) - { - return nr; - } - } +NickRequest *findrequestnick(const ci::string &nick) +{ + nickrequest_map::const_iterator it = NickRequestList.find(nick); + + if (it != NickRequestList.end()) + return it->second; return NULL; } -/* Return the NickAlias structure for the given nick, or NULL if the nick - * isn't registered. */ - NickAlias *findnick(const char *nick) { - NickAlias *na; - - if (!nick || !*nick) - { - Alog(LOG_DEBUG) << "findnick() called with NULL values"; - return NULL; - } - - for (na = nalists[HASH(nick)]; na; na = na->next) - { - if (stricmp(na->nick, nick) == 0) - { - return na; - } - } - return NULL; + return findnick(ci::string(nick)); } NickAlias *findnick(const std::string &nick) { - return findnick(nick.c_str()); + return findnick(ci::string(nick.c_str())); } -/*************************************************************************/ +NickAlias *findnick(const ci::string &nick) +{ + nickalias_map::const_iterator it = NickAliasList.find(nick); -/* Return the NickCore structure for the given nick, or NULL if the core - * doesn't exist. */ + if (it != NickAliasList.end()) + return it->second; + return NULL; +} + +/*************************************************************************/ NickCore *findcore(const char *nick) { - NickCore *nc; + return findcore(ci::string(nick)); +} - if (!nick || !*nick) - { - Alog(LOG_DEBUG) << "findcore() called with NULL values"; - return NULL; - } +NickCore *findcore(const std::string &nick) +{ + return findcore(ci::string(nick.c_str())); +} - for (nc = nclists[HASH(nick)]; nc; nc = nc->next) - { - if (stricmp(nc->display, nick) == 0) - { - return nc; - } - } +NickCore *findcore(const ci::string &nick) +{ + nickcore_map::const_iterator it = NickCoreList.find(nick); + if (it != NickCoreList.end()) + return it->second; return NULL; } @@ -497,78 +456,6 @@ bool is_on_access(User *u, NickCore *nc) /*************************************************************************/ -/* Insert a nick alias alphabetically into the database. */ - -void alpha_insert_alias(NickAlias * na) -{ - NickAlias *ptr, *prev; - char *nick; - int index; - - if (!na) - { - Alog(LOG_DEBUG) << "alpha_insert_alias called with NULL values"; - return; - } - - nick = na->nick; - index = HASH(nick); - - for (prev = NULL, ptr = nalists[index]; - ptr && stricmp(ptr->nick, nick) < 0; prev = ptr, ptr = ptr->next); - na->prev = prev; - na->next = ptr; - if (!prev) - nalists[index] = na; - else - prev->next = na; - if (ptr) - ptr->prev = na; -} - -/*************************************************************************/ - -/* Insert a nick core into the database. */ - -void insert_core(NickCore * nc) -{ - int index; - - if (!nc) - { - Alog(LOG_DEBUG) << "insert_core called with NULL values"; - return; - } - - index = HASH(nc->display); - - nc->prev = NULL; - nc->next = nclists[index]; - if (nc->next) - nc->next->prev = nc; - nclists[index] = nc; -} - -/*************************************************************************/ -void insert_requestnick(NickRequest * nr) -{ - int index = HASH(nr->nick); - if (!nr) - { - Alog(LOG_DEBUG) << "insert_requestnick called with NULL values"; - return; - } - - - nr->prev = NULL; - nr->next = nrlists[index]; - if (nr->next) - nr->next->prev = nr; - nrlists[index] = nr; -} - -/*************************************************************************/ - /* Sets nc->display to newdisplay. If newdisplay is NULL, it will change * it to the first alias in the list. */ @@ -576,40 +463,25 @@ void insert_requestnick(NickRequest * nr) void change_core_display(NickCore * nc, const char *newdisplay) { - /* - if (!newdisplay) { - NickAlias *na; - - if (nc->aliases.count <= 0) - return; - - na = static_cast<NickAlias *>(nc->aliases.list[0]); - newdisplay = na->nick; - } - */ /* Log ... */ FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(nc, newdisplay)); Alog() << Config.s_NickServ << ": changing " << nc->display << " nickname group display to " << newdisplay; /* Remove the core from the list */ - if (nc->next) - nc->next->prev = nc->prev; - if (nc->prev) - nc->prev->next = nc->next; - else - nclists[HASH(nc->display)] = nc->next; + NickCoreList.erase(nc->display); delete [] nc->display; nc->display = sstrdup(newdisplay); - insert_core(nc); + + NickCoreList[nc->display] = nc; } void change_core_display(NickCore * nc) { NickAlias *na; - if (nc->aliases.count <= 0) + if (nc->aliases.empty()) return; - na = static_cast<NickAlias *>(nc->aliases.list[0]); + na = nc->aliases.front(); change_core_display(nc,na->nick); } diff --git a/src/operserv.c b/src/operserv.c deleted file mode 100644 index 455d74923..000000000 --- a/src/operserv.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* OperServ functions. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "pseudo.h" - -/*************************************************************************/ - -/* AKILL, SGLINE, SQLINE and SZLINE lists */ -SList akills, sglines, sqlines, szlines; - -/*************************************************************************/ - -static int is_akill_entry_equal(SList * slist, void *item1, void *item2); -static void free_akill_entry(SList * slist, void *item); -static int is_sgline_entry_equal(SList * slist, void *item1, void *item2); -static void free_sgline_entry(SList * slist, void *item); -static int is_sqline_entry_equal(SList * slist, void *item1, void *item2); -static void free_sqline_entry(SList * slist, void *item); -static int is_szline_entry_equal(SList * slist, void *item1, void *item2); -static void free_szline_entry(SList * slist, void *item); - -/* News items */ -std::vector<NewsItem *> News; - -std::vector<std::bitset<32> > DefCon; -int DefConModesSet = 0; -/* Defcon modes mlocked on */ -Flags<ChannelModeName> DefConModesOn; -/* Defcon modes mlocked off */ -Flags<ChannelModeName> DefConModesOff; -/* Map of Modesa and Params for DefCon */ -std::map<ChannelModeName, std::string> DefConModesOnParams; - -bool SetDefConParam(ChannelModeName Name, std::string &buf) -{ - return DefConModesOnParams.insert(std::make_pair(Name, buf)).second; -} - -bool GetDefConParam(ChannelModeName Name, std::string *buf) -{ - std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name); - - buf->clear(); - - if (it != DefConModesOnParams.end()) - { - *buf = it->second; - return true; - } - - return false; -} - -void UnsetDefConParam(ChannelModeName Name) -{ - std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name); - - if (it != DefConModesOnParams.end()) - { - DefConModesOnParams.erase(it); - } -} - -/*************************************************************************/ - -void moduleAddOperServCmds(); -/*************************************************************************/ - -/* Options for the lists */ -SListOpts akopts = { 0, NULL, &is_akill_entry_equal, &free_akill_entry }; - -SListOpts sgopts = { 0, NULL, &is_sgline_entry_equal, &free_sgline_entry }; -SListOpts sqopts = - { SLISTF_SORT, NULL, &is_sqline_entry_equal, &free_sqline_entry }; -SListOpts szopts = { 0, NULL, &is_szline_entry_equal, &free_szline_entry }; - -/*************************************************************************/ -/* *INDENT-OFF* */ -void moduleAddOperServCmds() { - ModuleManager::LoadModuleList(Config.OperServCoreModules); -} - -/* *INDENT-ON* */ -/*************************************************************************/ -/*************************************************************************/ - -/* OperServ initialization. */ - -void os_init() -{ - moduleAddOperServCmds(); - - slist_init(&akills); - akills.opts = &akopts; - - if (ircd->sgline) { - slist_init(&sglines); - sglines.opts = &sgopts; - } - if (ircd->sqline) { - slist_init(&sqlines); - sqlines.opts = &sqopts; - } - if (ircd->szline) { - slist_init(&szlines); - szlines.opts = &szopts; - } -} - -/*************************************************************************/ - -/* Main OperServ routine. */ - -void operserv(User * u, char *buf) -{ - const char *cmd; - const char *s; - - Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf; - - cmd = strtok(buf, " "); - if (!cmd) { - return; - } else if (stricmp(cmd, "\1PING") == 0) { - if (!(s = strtok(NULL, ""))) { - s = ""; - } - ircdproto->SendCTCP(findbot(Config.s_OperServ), u->nick.c_str(), "PING %s", s); - } else { - mod_run_cmd(Config.s_OperServ, u, OPERSERV, cmd); - } -} - -/*************************************************************************/ -/*********************** OperServ command functions **********************/ -/*************************************************************************/ - -/*************************************************************************/ - - -Server *server_global(Server * s, char *msg) -{ - Server *sl; - - while (s) { - /* Do not send the notice to ourselves our juped servers */ - if (!s->HasFlag(SERVER_ISME) && !s->HasFlag(SERVER_JUPED)) - notice_server(Config.s_GlobalNoticer, s, "%s", msg); - - if (s->links) { - sl = server_global(s->links, msg); - if (sl) - s = sl; - else - s = s->next; - } else { - s = s->next; - } - } - return s; - -} - -void oper_global(char *nick, const char *fmt, ...) -{ - va_list args; - char msg[2048]; /* largest valid message is 512, this should cover any global */ - char dmsg[2048]; /* largest valid message is 512, this should cover any global */ - - va_start(args, fmt); - vsnprintf(msg, sizeof(msg), fmt, args); - va_end(args); - - /* I don't like the way this is coded... */ - if ((nick) && (!Config.AnonymousGlobal)) { - snprintf(dmsg, sizeof(dmsg), "[%s] %s", nick, msg); - server_global(servlist, dmsg); - } else { - server_global(servlist, msg); - } - -} - -/**************************************************************************/ - - -/************************************************************************/ -/*************************************************************************/ - -/* Adds an AKILL to the list. Returns >= 0 on success, -1 if it fails, -2 - * if only the expiry time was changed. - * The success result is the number of AKILLs that were deleted to successfully add one. - */ - -int add_akill(User * u, const char *mask, const char *by, const time_t expires, - const char *reason) -{ - int deleted = 0, i; - char *user, *mask2, *host; - Akill *entry; - - if (!mask) { - return -1; - } - - /* Checks whether there is an AKILL that already covers - * the one we want to add, and whether there are AKILLs - * that would be covered by this one. The masks AND the - * expiry times are used to determine this, because some - * AKILLs may become useful when another one expires. - * If so, warn the user in the first case and cleanup - * the useless AKILLs in the second. - */ - - if (akills.count > 0) { - - for (i = akills.count - 1; i >= 0; i--) { - char amask[BUFSIZE]; - - entry = static_cast<Akill *>(akills.list[i]); - - if (!entry) - continue; - - snprintf(amask, sizeof(amask), "%s@%s", entry->user, - entry->host); - - if (!stricmp(amask, mask)) { - /* We change the AKILL expiry time if its current one is less than the new. - * This is preferable to be sure we don't change an important AKILL - * accidentely. - */ - if (entry->expires >= expires || entry->expires == 0) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_AKILL_EXISTS, - mask); - return -1; - } else { - entry->expires = expires; - if (u) - notice_lang(Config.s_OperServ, u, OPER_AKILL_CHANGED, - amask); - return -2; - } - } - - if (Anope::Match(mask, amask, false) - && (entry->expires >= expires || entry->expires == 0)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_AKILL_ALREADY_COVERED, - mask, amask); - return -1; - } - - if (Anope::Match(amask, mask, false) - && (entry->expires <= expires || expires == 0)) { - slist_delete(&akills, i); - deleted++; - } - } - - } - - /* We can now check whether the list is full or not. */ - if (slist_full(&akills)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_AKILL_REACHED_LIMIT, - akills.limit); - return -1; - } - - /* We can now (really) add the AKILL. */ - mask2 = sstrdup(mask); - host = strchr(mask2, '@'); - - if (!host) { - delete [] mask2; - return -1; - } - - user = mask2; - *host = 0; - host++; - - entry = new Akill; - - if (!entry) { - delete [] mask2; - return -1; - } - - entry->user = sstrdup(user); - entry->host = sstrdup(host); - entry->by = sstrdup(by); - entry->reason = sstrdup(reason); - entry->seton = time(NULL); - entry->expires = expires; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, entry)); - if (MOD_RESULT == EVENT_STOP) - { - delete entry; - return -1; - } - - slist_add(&akills, entry); - - if (Config.AkillOnAdd) - ircdproto->SendAkill(entry); - - delete [] mask2; - - return deleted; -} - -/* Does the user match any AKILLs? */ - -int check_akill(const char *nick, const char *username, const char *host, - const char *vhost, const char *ip) -{ - int i; - Akill *ak; - - if (akills.count == 0) - return 0; - - for (i = 0; i < akills.count; i++) { - ak = static_cast<Akill *>(akills.list[i]); - if (!ak) - continue; - if (Anope::Match(username, ak->user, false) - && Anope::Match(host, ak->host, false)) { - ircdproto->SendAkill(ak); - return 1; - } - if (ircd->vhost) { - if (vhost) { - if (Anope::Match(username, ak->user, false) - && Anope::Match(vhost, ak->host, false)) { - ircdproto->SendAkill(ak); - return 1; - } - } - } - if (ircd->nickip) { - if (ip) { - if (Anope::Match(username, ak->user, false) - && Anope::Match(ip, ak->host, false)) { - ircdproto->SendAkill(ak); - return 1; - } - } - } - - } - - return 0; -} - -/* Delete any expired autokills. */ - -void expire_akills() -{ - int i; - time_t now = time(NULL); - Akill *ak; - - for (i = akills.count - 1; i >= 0; i--) { - ak = static_cast<Akill *>(akills.list[i]); - - if (!ak->expires || ak->expires > now) - continue; - - if (Config.WallAkillExpire) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "AKILL on %s@%s has expired", - ak->user, ak->host); - slist_delete(&akills, i); - } -} - -static void free_akill_entry(SList * slist, void *item) -{ - Akill *ak = static_cast<Akill *>(item); - - /* Remove the AKILLs from all the servers */ - ircdproto->SendAkillDel(ak); - - /* Free the structure */ - delete [] ak->user; - delete [] ak->host; - delete [] ak->by; - delete [] ak->reason; - delete ak; -} - -/* item1 is not an Akill pointer, but a char - */ - -static int is_akill_entry_equal(SList * slist, void *item1, void *item2) -{ - char *ak1 = static_cast<char *>(item1), buf[BUFSIZE]; - Akill *ak2 = static_cast<Akill *>(item2); - - if (!ak1 || !ak2) - return 0; - - snprintf(buf, sizeof(buf), "%s@%s", ak2->user, ak2->host); - - if (!stricmp(ak1, buf)) - return 1; - else - return 0; -} - - -/*************************************************************************/ - -/* Adds an SGLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if - * only the expiry time changed. - * The success result is the number of SGLINEs that were deleted to successfully add one. - */ - -int add_sgline(User * u, const char *mask, const char *by, time_t expires, - const char *reason) -{ - int deleted = 0, i; - SXLine *entry; - User *u2, *next; - char buf[BUFSIZE]; - *buf = '\0'; - - /* Checks whether there is an SGLINE that already covers - * the one we want to add, and whether there are SGLINEs - * that would be covered by this one. - * If so, warn the user in the first case and cleanup - * the useless SGLINEs in the second. - */ - - if (!mask) { - return -1; - } - - if (sglines.count > 0) { - - for (i = sglines.count - 1; i >= 0; i--) { - entry = static_cast<SXLine *>(sglines.list[i]); - - if (!entry) - continue; - - if (!stricmp(entry->mask, mask)) { - if (entry->expires >= expires || entry->expires == 0) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_EXISTS, - mask); - return -1; - } else { - entry->expires = expires; - if (u) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_CHANGED, - entry->mask); - return -2; - } - } - - if (Anope::Match(mask, entry->mask, false ) - && (entry->expires >= expires || entry->expires == 0)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_ALREADY_COVERED, - mask, entry->mask); - return -1; - } - - if (Anope::Match(entry->mask, mask, false) - && (entry->expires <= expires || expires == 0)) { - slist_delete(&sglines, i); - deleted++; - } - } - - } - - /* We can now check whether the list is full or not. */ - if (slist_full(&sglines)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SGLINE_REACHED_LIMIT, - sglines.limit); - return -1; - } - - /* We can now (really) add the SGLINE. */ - entry = new SXLine; - if (!entry) - return -1; - - entry->mask = sstrdup(mask); - entry->by = sstrdup(by); - entry->reason = sstrdup(reason); - entry->seton = time(NULL); - entry->expires = expires; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SGLINE)); - if (MOD_RESULT == EVENT_STOP) - { - delete entry; - return -1; - } - - slist_add(&sglines, entry); - - ircdproto->SendSGLine(entry); - - if (Config.KillonSGline && !ircd->sglineenforce) { - snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason); - u2 = firstuser(); - while (u2) { - next = nextuser(); - if (!is_oper(u2)) { - if (Anope::Match(u2->realname, entry->mask, false)) { - kill_user(Config.ServerName, u2->nick, buf); - } - } - u2 = next; - } - } - return deleted; -} - -/* Does the user match any SGLINEs? */ - -int check_sgline(const char *nick, const char *realname) -{ - int i; - SXLine *sx; - - if (sglines.count == 0) - return 0; - - for (i = 0; i < sglines.count; i++) { - sx = static_cast<SXLine *>(sglines.list[i]); - if (!sx) - continue; - - if (Anope::Match(realname, sx->mask, false)) { - ircdproto->SendSGLine(sx); - /* We kill nick since s_sgline can't */ - ircdproto->SendSVSKill(NULL, finduser(nick), "G-Lined: %s", sx->reason); - return 1; - } - } - - return 0; -} - -/* Delete any expired SGLINEs. */ - -void expire_sglines() -{ - int i; - time_t now = time(NULL); - SXLine *sx; - - for (i = sglines.count - 1; i >= 0; i--) { - sx = static_cast<SXLine *>(sglines.list[i]); - - if (!sx->expires || sx->expires > now) - continue; - - if (Config.WallSGLineExpire) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SGLINE on \2%s\2 has expired", - sx->mask); - slist_delete(&sglines, i); - } -} - -static void free_sgline_entry(SList * slist, void *item) -{ - SXLine *sx = static_cast<SXLine *>(item); - - /* Remove the SGLINE from all the servers */ - ircdproto->SendSGLineDel(sx); - - /* Free the structure */ - delete [] sx->mask; - delete [] sx->by; - delete [] sx->reason; - delete sx; -} - -/* item1 is not an SXLine pointer, but a char */ - -static int is_sgline_entry_equal(SList * slist, void *item1, void *item2) -{ - char *sx1 = static_cast<char *>(item1); - SXLine *sx2 = static_cast<SXLine *>(item2); - - if (!sx1 || !sx2) - return 0; - - if (!stricmp(sx1, sx2->mask)) - return 1; - else - return 0; -} - -/*************************************************************************/ - -/* Adds an SQLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if - * only the expiry time changed. - * The success result is the number of SQLINEs that were deleted to successfully add one. - */ - -int add_sqline(User * u, const char *mask, const char *by, time_t expires, - const char *reason) -{ - int deleted = 0, i; - User *u2, *next; - SXLine *entry; - char buf[BUFSIZE]; - *buf = '\0'; - - /* Checks whether there is an SQLINE that already covers - * the one we want to add, and whether there are SQLINEs - * that would be covered by this one. - * If so, warn the user in the first case and cleanup - * the useless SQLINEs in the second. - */ - - if (!mask) { - return -1; - } - - if (sqlines.count > 0) { - - for (i = sqlines.count - 1; i >= 0; i--) { - entry = static_cast<SXLine *>(sqlines.list[i]); - - if (!entry) - continue; - - if ((*mask == '#' && *entry->mask != '#') || - (*mask != '#' && *entry->mask == '#')) - continue; - - if (!stricmp(entry->mask, mask)) { - if (entry->expires >= expires || entry->expires == 0) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_EXISTS, - mask); - return -1; - } else { - entry->expires = expires; - if (u) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANGED, - entry->mask); - return -2; - } - } - - if (Anope::Match(mask, entry->mask, false) - && (entry->expires >= expires || entry->expires == 0)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_ALREADY_COVERED, - mask, entry->mask); - return -1; - } - - if (Anope::Match(entry->mask, mask, false) - && (entry->expires <= expires || expires == 0)) { - slist_delete(&sqlines, i); - deleted++; - } - } - - } - - /* We can now check whether the list is full or not. */ - if (slist_full(&sqlines)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SQLINE_REACHED_LIMIT, - sqlines.limit); - return -1; - } - - /* We can now (really) add the SQLINE. */ - entry = new SXLine; - if (!entry) - return -1; - - entry->mask = sstrdup(mask); - entry->by = sstrdup(by); - entry->reason = sstrdup(reason); - entry->seton = time(NULL); - entry->expires = expires; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SQLINE)); - if (MOD_RESULT == EVENT_STOP) - { - delete entry; - return -1; - } - - slist_add(&sqlines, entry); - - sqline(entry->mask, entry->reason); - - if (Config.KillonSQline) { - snprintf(buf, (BUFSIZE - 1), "Q-Lined: %s", entry->reason); - u2 = firstuser(); - while (u2) { - next = nextuser(); - if (!is_oper(u2)) { - if (Anope::Match(u2->nick, entry->mask, false)) { - kill_user(Config.ServerName, u2->nick, buf); - } - } - u2 = next; - } - } - - return deleted; -} - -/* Does the user match any SQLINEs? */ - -int check_sqline(const char *nick, int nick_change) -{ - int i; - SXLine *sx; - char reason[300]; - - if (sqlines.count == 0) - return 0; - - for (i = 0; i < sqlines.count; i++) { - sx = static_cast<SXLine *>(sqlines.list[i]); - if (!sx) - continue; - - if (ircd->chansqline) { - if (*sx->mask == '#') - continue; - } - - if (Anope::Match(nick, sx->mask, false)) { - sqline(sx->mask, sx->reason); - /* We kill nick since s_sqline can't */ - snprintf(reason, sizeof(reason), "Q-Lined: %s", sx->reason); - kill_user(Config.s_OperServ, nick, reason); - return 1; - } - } - - return 0; -} - -int check_chan_sqline(const char *chan) -{ - int i; - SXLine *sx; - - if (sqlines.count == 0) - return 0; - - for (i = 0; i < sqlines.count; i++) { - sx = static_cast<SXLine *>(sqlines.list[i]); - if (!sx) - continue; - - if (*sx->mask != '#') - continue; - - if (Anope::Match(chan, sx->mask, false)) { - sqline(sx->mask, sx->reason); - return 1; - } - } - - return 0; -} - -/* Delete any expired SQLINEs. */ - -void expire_sqlines() -{ - int i; - time_t now = time(NULL); - SXLine *sx; - - for (i = sqlines.count - 1; i >= 0; i--) { - sx = static_cast<SXLine *>(sqlines.list[i]); - - if (!sx->expires || sx->expires > now) - continue; - - if (Config.WallSQLineExpire) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SQLINE on \2%s\2 has expired", - sx->mask); - - slist_delete(&sqlines, i); - } -} - -static void free_sqline_entry(SList * slist, void *item) -{ - SXLine *sx = static_cast<SXLine *>(item); - - /* Remove the SQLINE from all the servers */ - ircdproto->SendSQLineDel(sx->mask); - - /* Free the structure */ - delete [] sx->mask; - delete [] sx->by; - delete [] sx->reason; - delete sx; -} - -/* item1 is not an SXLine pointer, but a char */ - -static int is_sqline_entry_equal(SList * slist, void *item1, void *item2) -{ - char *sx1 = static_cast<char *>(item1); - SXLine *sx2 = static_cast<SXLine *>(item2); - - if (!sx1 || !sx2) - return 0; - - if (!stricmp(sx1, sx2->mask)) - return 1; - else - return 0; -} - -/*************************************************************************/ - -/* Adds an SZLINE to the list. Returns >= 0 on success, -1 on error, -2 if - * only the expiry time changed. - * The success result is the number of SZLINEs that were deleted to successfully add one. - */ - -int add_szline(User * u, const char *mask, const char *by, time_t expires, - const char *reason) -{ - int deleted = 0, i; - SXLine *entry; - - if (!mask) { - return -1; - } - - /* Checks whether there is an SZLINE that already covers - * the one we want to add, and whether there are SZLINEs - * that would be covered by this one. - * If so, warn the user in the first case and cleanup - * the useless SZLINEs in the second. - */ - - if (szlines.count > 0) { - - for (i = szlines.count - 1; i >= 0; i--) { - entry = static_cast<SXLine *>(szlines.list[i]); - - if (!entry) - continue; - - if (!stricmp(entry->mask, mask)) { - if (entry->expires >= expires || entry->expires == 0) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS, - mask); - return -1; - } else { - entry->expires = expires; - if (u) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS, - mask); - return -2; - } - } - - if (Anope::Match(mask, entry->mask, false)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_ALREADY_COVERED, - mask, entry->mask); - return -1; - } - - if (Anope::Match(entry->mask, mask, false)) { - slist_delete(&szlines, i); - deleted++; - } - } - - } - - /* We can now check whether the list is full or not. */ - if (slist_full(&szlines)) { - if (u) - notice_lang(Config.s_OperServ, u, OPER_SZLINE_REACHED_LIMIT, - szlines.limit); - return -1; - } - - /* We can now (really) add the SZLINE. */ - entry = new SXLine; - if (!entry) - return -1; - - entry->mask = sstrdup(mask); - entry->by = sstrdup(by); - entry->reason = sstrdup(reason); - entry->seton = time(NULL); - entry->expires = expires; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SZLINE)); - if (MOD_RESULT == EVENT_STOP) - { - delete entry; - return -1; - } - - slist_add(&szlines, entry); - ircdproto->SendSZLine(entry); - - return deleted; -} - -/* Check and enforce any Zlines that we have */ -int check_szline(const char *nick, char *ip) -{ - int i; - SXLine *sx; - - if (szlines.count == 0) { - return 0; - } - - if (!ip) { - return 0; - } - - for (i = 0; i < szlines.count; i++) { - sx = static_cast<SXLine *>(szlines.list[i]); - if (!sx) { - continue; - } - - if (Anope::Match(ip, sx->mask, false)) { - ircdproto->SendSZLine(sx); - return 1; - } - } - - return 0; -} - - -/* Delete any expired SZLINEs. */ - -void expire_szlines() -{ - int i; - time_t now = time(NULL); - SXLine *sx; - - for (i = szlines.count - 1; i >= 0; i--) { - sx = static_cast<SXLine *>(szlines.list[i]); - - if (!sx->expires || sx->expires > now) - continue; - - if (Config.WallSZLineExpire) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SZLINE on \2%s\2 has expired", - sx->mask); - slist_delete(&szlines, i); - } -} - -static void free_szline_entry(SList * slist, void *item) -{ - SXLine *sx = static_cast<SXLine *>(item); - - /* Remove the SZLINE from all the servers */ - ircdproto->SendSZLineDel(sx); - - /* Free the structure */ - delete [] sx->mask; - delete [] sx->by; - delete [] sx->reason; - delete sx; -} - -/* item1 is not an SXLine pointer, but a char - */ - -static int is_szline_entry_equal(SList * slist, void *item1, void *item2) -{ - char *sx1 = static_cast<char *>(item1); - SXLine *sx2 = static_cast<SXLine *>(item2); - - if (!sx1 || !sx2) - return 0; - - if (!stricmp(sx1, sx2->mask)) - return 1; - else - return 0; -} - -/*************************************************************************/ - -/** Check if a certain defcon option is currently in affect - * @param Level The level - * @return true and false - */ -bool CheckDefCon(DefconLevel Level) -{ - if (Config.DefConLevel) - return DefCon[Config.DefConLevel][Level]; - return false; -} - -/** Check if a certain defcon option is in a certain defcon level - * @param level The defcon level - * @param Level The defcon level name - * @return true or false - */ -bool CheckDefCon(int level, DefconLevel Level) -{ - return DefCon[level][Level]; -} - -/** Add a defcon level option to a defcon level - * @param level The defcon level - * @param Level The defcon level option - */ -void AddDefCon(int level, DefconLevel Level) -{ - DefCon[level][Level] = true; -} - -/** Remove a defcon level option from a defcon level - * @param level The defcon level - * @param Level The defcon level option - */ -void DelDefCon(int level, DefconLevel Level) -{ - DefCon[level][Level] = false; -} - diff --git a/src/operserv.cpp b/src/operserv.cpp new file mode 100644 index 000000000..8e3a3c90f --- /dev/null +++ b/src/operserv.cpp @@ -0,0 +1,828 @@ +/* OperServ functions. + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * + */ + +#include "services.h" +#include "modules.h" +#include "language.h" + +std::vector<NewsItem *> News; + +std::vector<std::bitset<32> > DefCon; +bool DefConModesSet = false; +/* Defcon modes mlocked on */ +Flags<ChannelModeName> DefConModesOn; +/* Defcon modes mlocked off */ +Flags<ChannelModeName> DefConModesOff; +/* Map of Modesa and Params for DefCon */ +std::map<ChannelModeName, std::string> DefConModesOnParams; + +XLineManager *SGLine, *SZLine, *SQLine, *SNLine; + +void os_init() +{ + ModuleManager::LoadModuleList(Config.OperServCoreModules); + + /* Yes, these are in this order for a reason. Most violent->least violent. */ + XLineManager::RegisterXLineManager(SGLine = new SGLineManager()); + XLineManager::RegisterXLineManager(SZLine = new SZLineManager()); + XLineManager::RegisterXLineManager(SQLine = new SQLineManager()); + XLineManager::RegisterXLineManager(SNLine = new SNLineManager()); +} + +void operserv(User *u, const std::string &buf) +{ + if (!u || buf.empty()) + return; + + Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf; + + if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1') + { + std::string command = buf; + command.erase(command.begin()); + command.erase(command.end()); + ircdproto->SendCTCP(OperServ, u->nick.c_str(), "%s", command.c_str()); + } + else + { + mod_run_cmd(OperServ, u, buf); + } +} + +bool SetDefConParam(ChannelModeName Name, std::string &buf) +{ + return DefConModesOnParams.insert(std::make_pair(Name, buf)).second; +} + +bool GetDefConParam(ChannelModeName Name, std::string &buf) +{ + std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name); + + buf.clear(); + + if (it != DefConModesOnParams.end()) + { + buf = it->second; + return true; + } + + return false; +} + +void UnsetDefConParam(ChannelModeName Name) +{ + std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name); + + if (it != DefConModesOnParams.end()) + { + DefConModesOnParams.erase(it); + } +} + +/** Check if a certain defcon option is currently in affect + * @param Level The level + * @return true and false + */ +bool CheckDefCon(DefconLevel Level) +{ + if (Config.DefConLevel) + return DefCon[Config.DefConLevel][Level]; + return false; +} + +/** Check if a certain defcon option is in a certain defcon level + * @param level The defcon level + * @param Level The defcon level name + * @return true or false + */ +bool CheckDefCon(int level, DefconLevel Level) +{ + return DefCon[level][Level]; +} + +/** Add a defcon level option to a defcon level + * @param level The defcon level + * @param Level The defcon level option + */ +void AddDefCon(int level, DefconLevel Level) +{ + DefCon[level][Level] = true; +} + +/** Remove a defcon level option from a defcon level + * @param level The defcon level + * @param Level The defcon level option + */ +void DelDefCon(int level, DefconLevel Level) +{ + DefCon[level][Level] = false; +} + +void server_global(Server *s, const std::string &message) +{ + /* Do not send the notice to ourselves our juped servers */ + if (s != Me && !s->HasFlag(SERVER_JUPED)) + notice_server(Config.s_GlobalNoticer, s, "%s", message.c_str()); + + if (s->GetLinks()) + { + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + server_global(*it, message); + } + } +} + +void oper_global(char *nick, const char *fmt, ...) +{ + va_list args; + char msg[2048]; /* largest valid message is 512, this should cover any global */ + + va_start(args, fmt); + vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + + if (nick && !Config.AnonymousGlobal) + { + std::string rmsg = std::string("[") + nick + std::string("] ") + msg; + server_global(Me->GetUplink(), rmsg.c_str()); + } + else + server_global(Me->GetUplink(), msg); + +} + +/**************************************************************************/ + +/* List of XLine managers we check users against in XLineManager::CheckAll */ +std::list<XLineManager *> XLineManager::XLineManagers; + +XLine::XLine(const ci::string &mask, const std::string &reason) : Mask(mask), Reason(reason) +{ + Expires = Created = 0; +} + +XLine::XLine(const ci::string &mask, const ci::string &by, const time_t expires, const std::string &reason) : Mask(mask), By(by), Created(time(NULL)), Expires(expires), Reason(reason) +{ +} + +ci::string XLine::GetNick() const +{ + size_t nick_t = Mask.find('!'); + + if (nick_t == ci::string::npos) + return ""; + + return Mask.substr(0, nick_t - 1); +} + +ci::string XLine::GetUser() const +{ + size_t user_t = Mask.find('!'), host_t = Mask.find('@'); + + if (user_t == ci::string::npos) + { + return Mask.substr(0, host_t); + } + else if (host_t != ci::string::npos) + { + return Mask.substr((user_t != ci::string::npos ? user_t + 1 : 0), host_t); + } + else + { + return ""; + } +} + +ci::string XLine::GetHost() const +{ + size_t host_t = Mask.find('@'); + + if (host_t == ci::string::npos) + { + return Mask; + } + else + { + return Mask.substr(host_t + 1); + } +} + +/** Constructor + */ +XLineManager::XLineManager() +{ +} + +/** Destructor + * Clears all XLines in this XLineManager + */ +XLineManager::~XLineManager() +{ + Clear(); +} + + /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll + * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling + * clients and one handing them free olines, you would want the akilling one first. This way if a client + * matches an entry on both of the XLineManagers, they would be akilled. + * @param xlm THe XLineManager + */ +void XLineManager::RegisterXLineManager(XLineManager *xlm) +{ + XLineManagers.push_back(xlm); +} + +/** Unregister a XLineManager + * @param xlm The XLineManager + */ +void XLineManager::UnregisterXLineManager(XLineManager *xlm) +{ + std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm); + + if (it != XLineManagers.end()) + { + XLineManagers.erase(it); + } +} + +/* Check a user against all known XLineManagers + * @param u The user + * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match + */ +std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u) +{ + std::pair<XLineManager *, XLine *> ret(NULL, NULL); + + for (std::list<XLineManager *>::iterator it = XLineManagers.begin(); it != XLineManagers.end(); ++it) + { + XLineManager *xlm = *it; + + XLine *x = xlm->Check(u); + + if (x) + { + ret.first = xlm; + ret.second = x;; + break; + } + } + + return ret; +} + +/** Get the number of XLines in this XLineManager + * @return The number of XLines + */ +const size_t XLineManager::GetCount() const +{ + return XLines.size(); +} + +/** Get the XLine list + * @return The list + */ +const std::deque<XLine *>& XLineManager::GetList() const +{ + return XLines; +} + +/** Add an entry to this XLineManager + * @param x The entry + */ +void XLineManager::AddXLine(XLine *x) +{ + XLines.push_back(x); +} + +/** Delete an entry from this XLineManager + * @param x The entry + * @return true if the entry was found and deleted, else false + */ +bool XLineManager::DelXLine(XLine *x) +{ + std::deque<XLine *>::iterator it = std::find(XLines.begin(), XLines.end(), x); + + if (it != XLines.end()) + { + delete x; + XLines.erase(it); + + return true; + } + + return false; +} + +/** Gets an entry by index + * @param index The index + * @return The XLine, or NULL if the index is out of bounds + */ +XLine *XLineManager::GetEntry(unsigned index) const +{ + if (index >= XLines.size()) + return NULL; + + return XLines[index]; +} + +/** Clear the XLine list + */ +void XLineManager::Clear() +{ + for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it) + { + delete *it; + } + XLines.clear(); +} + +/** Add an entry to this XLine Manager + * @param bi The bot error replies should be sent from + * @param u The user adding the XLine + * @param mask The mask of the XLine + * @param expires When this should expire + * @param reaosn The reason + * @return A pointer to the XLine + */ +XLine *XLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason) +{ + return NULL; +} + +/** Delete an XLine, eg, remove it from the IRCd. + * @param x The xline + */ +void XLineManager::Del(XLine *x) +{ +} + +/** Checks if a mask can/should be added to the XLineManager + * @param mask The mask + * @param expires When the mask would expire + * @return A pair of int and XLine*. + * 1 - Mask already exists + * 2 - Mask already exists, but the expiry time was changed + * 3 - Mask is already covered by another mask + * In each case the XLine it matches/is covered by is returned in XLine* + */ +std::pair<int, XLine *> XLineManager::CanAdd(const ci::string &mask, time_t expires) +{ + std::pair<int, XLine *> ret(0, NULL); + + for (unsigned i = 0; i < GetCount(); ++i) + { + XLine *x = GetEntry(i); + ret.second = x; + + if (x->Mask == mask) + { + if (x->Expires == 0 || x->Expires >= expires) + { + ret.first = 1; + break; + } + else + { + x->Expires = expires; + + ret.first = 2; + break; + } + } + else if (Anope::Match(mask, x->Mask) && (x->Expires == 0 || x->Expires >= expires)) + { + ret.first = 3; + break; + } + else if (Anope::Match(x->Mask, mask) && (expires == 0 || x->Expires <= expires)) + { + this->DelXLine(x); + --i; + } + } + + return ret; +} + +/** Checks if this list has an entry + * @param mask The mask + * @return The XLine the user matches, or NULL + */ +XLine *XLineManager::HasEntry(const ci::string &mask) const +{ + for (unsigned i = 0; i < XLines.size(); ++i) + { + XLine *x = XLines[i]; + + if (x->Mask == mask) + { + return x; + } + } + + return NULL; +} + +/** Check a user against all of the xlines in this XLineManager + * @param u The user + * @return The xline the user marches, if any. Also calls OnMatch() + */ +XLine *XLineManager::Check(User *u) +{ + const time_t now = time(NULL); + + for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it) + { + XLine *x = *it; + + if (x->Expires && x->Expires < now) + { + OnExpire(x); + delete x; + it = XLines.erase(it); + --it; + continue; + } + + if (!x->GetNick().empty() && !Anope::Match(u->nick.c_str(), x->GetNick())) + continue; + + if (!x->GetUser().empty() && !Anope::Match(u->GetIdent().c_str(), x->GetUser())) + continue; + + if (x->GetHost().empty() || ((u->hostip && Anope::Match(u->hostip, x->GetHost())) || Anope::Match(u->host, x->GetHost()) || (!u->chost.empty() && Anope::Match(u->chost.c_str(), x->GetHost())) || (u->vhost && Anope::Match(u->vhost, x->GetHost())))) + { + OnMatch(u, x); + return x; + } + } + + return NULL; +} + +/** Called when a user matches a xline in this XLineManager + * @param u The user + * @param x The XLine they match + */ +void XLineManager::OnMatch(User *u, XLine *x) +{ +} + +/** Called when an XLine expires + * @param x The xline + */ +void XLineManager::OnExpire(XLine *x) +{ +} + +XLine *SGLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason) +{ + if (mask.find('!') != ci::string::npos) + { + if (bi && u) + notice_lang(bi->nick.c_str(), u, OPER_AKILL_NO_NICK); + return NULL; + } + + if (mask.find('@') == ci::string::npos) + { + if (bi && u) + notice_lang(bi->nick.c_str(), u, BAD_USERHOST_MASK); + return NULL; + } + + if (strspn(mask.c_str(), "~@.*?") == mask.length()) + { + if (bi && u) + notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str()); + return NULL; + } + + std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires); + if (canAdd.first) + { + if (bi && u) + { + if (canAdd.first == 1) + notice_lang(bi->nick.c_str(), u, OPER_AKILL_EXISTS, canAdd.second->Mask.c_str()); + else if (canAdd.first == 2) + notice_lang(bi->nick.c_str(), u, OPER_AKILL_CHANGED, canAdd.second->Mask.c_str()); + else if (canAdd.first == 3) + notice_lang(bi->nick.c_str(), u, OPER_AKILL_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str()); + } + + return canAdd.second; + } + + std::string realreason = reason; + if (u && Config.AddAkiller) + realreason = "[" + u->nick + "]" + reason; + + XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, realreason); + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, x)); + if (MOD_RESULT == EVENT_STOP) + { + delete x; + return NULL; + } + + this->AddXLine(x); + + if (Config.AkillOnAdd) + ircdproto->SendAkill(x); + + return x; +} + +void SGLineManager::Del(XLine *x) +{ + ircdproto->SendAkillDel(x); +} + +void SGLineManager::OnMatch(User *u, XLine *x) +{ + ircdproto->SendAkill(x); +} + +void SGLineManager::OnExpire(XLine *x) +{ + if (Config.WallAkillExpire) + ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str()); +} + +XLine *SNLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason) +{ + if (!mask.empty() && strspn(mask.c_str(), "*?") == mask.length()) + { + if (bi && u) + notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str()); + return NULL; + } + + std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires); + if (canAdd.first) + { + if (bi && u) + { + if (canAdd.first == 1) + notice_lang(bi->nick.c_str(), u, OPER_SNLINE_EXISTS, canAdd.second->Mask.c_str()); + else if (canAdd.first == 2) + notice_lang(bi->nick.c_str(), u, OPER_SNLINE_CHANGED, canAdd.second->Mask.c_str()); + else if (canAdd.first == 3) + notice_lang(bi->nick.c_str(), u, OPER_SNLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str()); + } + + return canAdd.second; + } + + XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason); + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SNLINE)); + if (MOD_RESULT == EVENT_STOP) + { + delete x; + return NULL; + } + + this->AddXLine(x); + + if (Config.KillonSNline && !ircd->sglineenforce) + { + std::string rreason = "G-Lined: " + reason; + + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *user = it->second; + ++it; + + if (!is_oper(user) && Anope::Match(user->realname, x->Mask)) + { + kill_user(Config.ServerName, user->nick, rreason.c_str()); + } + } + } + + return x; +} + +void SNLineManager::Del(XLine *x) +{ + ircdproto->SendSGLineDel(x); +} + +void SNLineManager::OnMatch(User *u, XLine *x) +{ + ircdproto->SendSGLine(x); + + std::string reason = "G-Lined: " + x->Reason; + kill_user(Config.s_OperServ, u->nick, reason.c_str()); +} + +void SNLineManager::OnExpire(XLine *x) +{ + if (Config.WallSNLineExpire) + ircdproto->SendGlobops(OperServ, "SNLINE on \2%s\2 has expired", x->Mask.c_str()); +} + +XLine *SQLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason) +{ + if (strspn(mask.c_str(), "*") == mask.length()) + { + if (bi && u) + notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str()); + return NULL; + } + + if (mask[0] == '#' && !ircd->chansqline) + { + if (bi && u) + notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED); + return NULL; + } + + std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires); + if (canAdd.first) + { + if (bi && u) + { + if (canAdd.first == 1) + notice_lang(bi->nick.c_str(), u, OPER_SQLINE_EXISTS, canAdd.second->Mask.c_str()); + else if (canAdd.first == 2) + notice_lang(bi->nick.c_str(), u, OPER_SQLINE_CHANGED, canAdd.second->Mask.c_str()); + else if (canAdd.first == 3) + notice_lang(bi->nick.c_str(), u, OPER_SQLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str()); + } + + return canAdd.second; + } + + XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason); + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SQLINE)); + if (MOD_RESULT == EVENT_STOP) + { + delete x; + return NULL; + } + + this->AddXLine(x); + + if (Config.KillonSQline) + { + std::string rreason = "Q-Lined: " + reason; + + if (mask[0] == '#') + { + for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit) + { + Channel *c = cit->second; + + if (!Anope::Match(c->name.c_str(), mask)) + continue; + for (CUserList::iterator it = c->users.begin(); it != c->users.end();) + { + UserContainer *uc = *it; + ++it; + + if (is_oper(uc->user)) + continue; + c->Kick(NULL, uc->user, "%s", reason.c_str()); + } + } + } + else + { + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *user = it->second; + ++it; + + if (!is_oper(user) && Anope::Match(user->nick.c_str(), x->Mask)) + { + kill_user(Config.ServerName, user->nick, rreason.c_str()); + } + } + } + } + + ircdproto->SendSQLine(x); + + return x; +} + +void SQLineManager::Del(XLine *x) +{ + ircdproto->SendSQLineDel(x); +} + +void SQLineManager::OnMatch(User *u, XLine *x) +{ + ircdproto->SendSQLine(x); + + char reason[300]; + snprintf(reason, sizeof(reason), "Q-Lined: %s", x->Reason.c_str()); + kill_user(Config.s_OperServ, u->nick, reason); +} + +void SQLineManager::OnExpire(XLine *x) +{ + if (Config.WallSQLineExpire) + ircdproto->SendGlobops(OperServ, "SQLINE on \2%s\2 has expired", x->Mask.c_str()); +} + +bool SQLineManager::Check(Channel *c) +{ + if (ircd->chansqline && SQLine) + { + for (std::deque<XLine *>::const_iterator it = SGLine->GetList().begin(); it != SGLine->GetList().end(); ++it) + { + XLine *x = *it; + + if (Anope::Match(c->name.c_str(), x->Mask)) + { + return true; + } + } + } + + return false; +} + +XLine *SZLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason) +{ + if (mask.find('!') != ci::string::npos || mask.find('@') != ci::string::npos) + { + notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS); + return NULL; + } + + if (strspn(mask.c_str(), "*?") == mask.length()) + { + notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str()); + return NULL; + } + + std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires); + if (canAdd.first) + { + if (bi && u) + { + if (canAdd.first == 1) + notice_lang(bi->nick.c_str(), u, OPER_SZLINE_EXISTS, canAdd.second->Mask.c_str()); + else if (canAdd.first == 2) + notice_lang(bi->nick.c_str(), u, OPER_SZLINE_CHANGED, canAdd.second->Mask.c_str()); + else if (canAdd.first == 3) + notice_lang(bi->nick.c_str(), u, OPER_SZLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str()); + } + + return canAdd.second; + } + + XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason); + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SZLINE)); + if (MOD_RESULT == EVENT_STOP) + { + delete x; + return NULL; + } + + this->AddXLine(x); + + ircdproto->SendSZLine(x); + + return x; +} + +void SZLineManager::Del(XLine *x) +{ + ircdproto->SendSZLineDel(x); +} + +void SZLineManager::OnMatch(User *u, XLine *x) +{ + ircdproto->SendSZLine(x); +} + +void SZLineManager::OnExpire(XLine *x) +{ + if (Config.WallSZLineExpire) + ircdproto->SendGlobops(OperServ, "SZLINE on \2%s\2 has expired", x->Mask.c_str()); +} + diff --git a/src/opertype.cpp b/src/opertype.cpp index fb0689add..0ee6d000f 100644 --- a/src/opertype.cpp +++ b/src/opertype.cpp @@ -16,26 +16,44 @@ OperType::OperType(const ci::string &nname) : name(nname) bool OperType::HasCommand(const std::string &cmdstr) const { - for (std::list<std::string>::const_iterator it = this->commands.begin(); it != this->commands.end(); it++) + for (std::list<std::string>::const_iterator it = this->commands.begin(); it != this->commands.end(); ++it) { if (Anope::Match(cmdstr, *it)) { return true; } } + for (std::set<OperType *>::const_iterator iit = this->inheritances.begin(); iit != this->inheritances.end(); ++iit) + { + OperType *ot = *iit; + + if (ot->HasCommand(cmdstr)) + { + return true; + } + } return false; } bool OperType::HasPriv(const std::string &privstr) const { - for (std::list<std::string>::const_iterator it = this->privs.begin(); it != this->privs.end(); it++) + for (std::list<std::string>::const_iterator it = this->privs.begin(); it != this->privs.end(); ++it) { if (Anope::Match(privstr, *it)) { return true; } } + for (std::set<OperType *>::const_iterator iit = this->inheritances.begin(); iit != this->inheritances.end(); ++iit) + { + OperType *ot = *iit; + + if (ot->HasPriv(privstr)) + { + return true; + } + } return false; } @@ -55,3 +73,8 @@ const ci::string &OperType::GetName() const return this->name; } +void OperType::Inherits(OperType *ot) +{ + this->inheritances.insert(ot); +} + diff --git a/src/process.c b/src/process.cpp index ca9e2c069..7a015c64b 100644 --- a/src/process.c +++ b/src/process.cpp @@ -12,7 +12,6 @@ */ #include "services.h" -#include "messages.h" #include "modules.h" /*************************************************************************/ @@ -283,14 +282,12 @@ int split_buf(char *buf, const char ***argv, int colon_special) void process(const std::string &buffer) { int retVal = 0; - Message *current = NULL; char source[64]; char cmd[64]; char buf[512]; /* Longest legal IRC command line */ char *s; int ac; /* Parameters for the command */ const char **av; - Message *m; /* zero out the buffers before we do much else */ *buf = '\0'; @@ -346,19 +343,21 @@ void process(const std::string &buffer) } /* Do something with the message. */ - m = find_message(cmd); - if (m) { - if (m->func) { - retVal = m->func(source, ac, av); - if (retVal == MOD_CONT) { - current = m->next; - while (current && current->func && retVal == MOD_CONT) { - retVal = current->func(source, ac, av); - current = current->next; - } - } + std::vector<Message *> messages = FindMessage(cmd); + + if (!messages.empty()) + { + retVal = MOD_CONT; + + for (std::vector<Message *>::iterator it = messages.begin(); retVal == MOD_CONT && it != messages.end(); ++it) + { + Message *m = *it; + + if (m->func) + retVal = m->func(source, ac, av); } - } else + } + else Alog(LOG_DEBUG) << "unknown message from server (" << buffer << ")"; /* Free argument list we created */ diff --git a/src/protocol.cpp b/src/protocol.cpp index 2188e86ba..761df1ca1 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -153,12 +153,12 @@ void IRCDProto::SendPrivmsg(BotInfo *bi, const char *dest, const char *fmt, ...) void IRCDProto::SendGlobalNotice(BotInfo *bi, Server *dest, const char *msg) { - send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->name, msg); + send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg); } void IRCDProto::SendGlobalPrivmsg(BotInfo *bi, Server *dest, const char *msg) { - send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->name, msg); + send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg); } void IRCDProto::SendQuit(const char *nick, const char *) diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt index a74b49a89..abca56caf 100644 --- a/src/protocol/CMakeLists.txt +++ b/src/protocol/CMakeLists.txt @@ -1,5 +1,4 @@ -# Find all the *.c and *.cpp files within the current source directory, and sort the list -file(GLOB PROTOCOL_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") +# Find all the *.cpp files within the current source directory, and sort the list file(GLOB PROTOCOL_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") set(PROTOCOL_SRCS ${PROTOCOL_SRCS_C} ${PROTOCOL_SRCS_CPP}) sort_list(PROTOCOL_SRCS) diff --git a/src/protocol/Makefile b/src/protocol/Makefile index a40d009c2..7221ab2e2 100644 --- a/src/protocol/Makefile +++ b/src/protocol/Makefile @@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}'\ 'MAKEBIN=${MAKEBIN}' -OBJECTS= $(SRCS:.c=.so) -OBJECTS+= $(SRCS:.cpp=.so) +OBJECTS= $(SRCS:.cpp=.so) CDEFS= -rdynamic -Wall all: modules subs @@ -21,10 +20,7 @@ install: distclean: clean spotless -.SUFFIXES: .c .cpp .so - -.c.so: - $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $< +.SUFFIXES: .cpp .so .cpp.so: $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $< diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.cpp index 1e38a4aa2..d55a08123 100644 --- a/src/protocol/bahamut.c +++ b/src/protocol/bahamut.cpp @@ -14,7 +14,7 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" IRCDVar myIrcd[] = { {"Bahamut 1.8.x", /* ircd name */ @@ -23,7 +23,7 @@ IRCDVar myIrcd[] = { "+o", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 0, /* Vhost */ - 1, /* Supports SGlines */ + 1, /* Supports SNlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ 3, /* Number of server args */ @@ -141,35 +141,33 @@ class BahamutIRCdProto : public IRCDProto } /* SQLINE */ - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(NULL, "SQLINE %s :%s", mask.c_str(), reason.c_str()); + send_cmd(NULL, "SQLINE %s :%s", x->Mask.c_str(), x->Reason.c_str()); } - /* UNSGLINE */ - void SendSGLineDel(SXLine *sx) + /* UNSLINE */ + void SendSGLineDel(XLine *x) { - send_cmd(NULL, "UNSGLINE 0 :%s", sx->mask); + send_cmd(NULL, "UNSGLINE 0 :%s", x->Mask.c_str()); } /* UNSZLINE */ - void SendSZLineDel(SXLine *sx) + void SendSZLineDel(XLine *x) { /* this will likely fail so its only here for legacy */ - send_cmd(NULL, "UNSZLINE 0 %s", sx->mask); + send_cmd(NULL, "UNSZLINE 0 %s", x->Mask.c_str()); /* this is how we are supposed to deal with it */ - send_cmd(NULL, "RAKILL %s *", sx->mask); + send_cmd(NULL, "RAKILL %s *", x->Mask.c_str()); } /* SZLINE */ - void SendSZLine(SXLine *sx) + void SendSZLine(XLine *x) { /* this will likely fail so its only here for legacy */ - send_cmd(NULL, "SZLINE %s :%s", sx->mask, sx->reason); + send_cmd(NULL, "SZLINE %s :%s", x->Mask.c_str(), x->Reason.c_str()); /* this is how we are supposed to deal with it */ - send_cmd(NULL, "AKILL %s * %d %s %ld :%s", sx->mask, 172800, sx->by, static_cast<long>(time(NULL)), sx->reason); + send_cmd(NULL, "AKILL %s * %d %s %ld :%s", x->Mask.c_str(), 172800, x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SVSNOOP */ @@ -179,15 +177,15 @@ class BahamutIRCdProto : public IRCDProto } /* SGLINE */ - void SendSGLine(SXLine *sx) + void SendSGLine(XLine *x) { - send_cmd(NULL, "SGLINE %d :%s:%s", static_cast<int>(strlen(sx->mask)), sx->mask, sx->reason); + send_cmd(NULL, "SGLINE %d :%s:%s", static_cast<int>(x->Mask.length()), x->Mask.c_str(), x->Reason.c_str()); } /* RAKILL */ - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - send_cmd(NULL, "RAKILL %s %s", ak->host, ak->user); + send_cmd(NULL, "RAKILL %s %s", x->GetHost().c_str(), x->GetUser().c_str()); } /* TOPIC */ @@ -197,11 +195,9 @@ class BahamutIRCdProto : public IRCDProto } /* UNSQLINE */ - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(NULL, "UNSQLINE %s", user.c_str()); + send_cmd(NULL, "UNSQLINE %s", x->Mask.c_str()); } /* JOIN - SJOIN */ @@ -210,12 +206,12 @@ class BahamutIRCdProto : public IRCDProto send_cmd(user->nick, "SJOIN %ld %s", static_cast<long>(chantime), channel); } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = ak->expires - time(NULL); + time_t timeleft = x->Expires - time(NULL); if (timeleft > 172800) timeleft = 172800; - send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", ak->host, ak->user, static_cast<int>(timeleft), ak->by, static_cast<long>(time(NULL)), ak->reason); + send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", x->GetHost().c_str(), x->GetUser().c_str(), static_cast<int>(timeleft), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* @@ -265,7 +261,7 @@ class BahamutIRCdProto : public IRCDProto /* nc_change was = 1, and there is no na->status */ void SendUnregisteredNick(User *u) { - BotInfo *bi = findbot(Config.s_NickServ); + BotInfo *bi = NickServ; u->RemoveMode(bi, UMODE_REGISTERED); ircdproto->SendMode(bi, u, "+d 1"); } @@ -273,15 +269,15 @@ class BahamutIRCdProto : public IRCDProto /* SERVER */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, ""); bahamut_cmd_pass(uplink_server->password); bahamut_cmd_capab(); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, ""); - SendServer(me_server); + SendServer(Me); bahamut_cmd_svinfo(); bahamut_cmd_burst(); } @@ -299,7 +295,7 @@ class BahamutIRCdProto : public IRCDProto u->Account()->Shrink("authenticationtoken"); u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf))); - BotInfo *bi = findbot(Config.s_NickServ); + BotInfo *bi = NickServ; u->SetMode(bi, UMODE_REGISTERED); ircdproto->SendMode(bi, u, "+d %s", svidbuf); } @@ -575,11 +571,7 @@ int anope_event_436(const char *source, int ac, const char **av) /* EVENT : SERVER */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); - } - - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); return MOD_CONT; } @@ -711,8 +703,8 @@ int anope_event_error(const char *source, int ac, const char **av) int anope_event_burst(const char *source, int ac, const char **av) { - Server *s; - s = findserver(servlist, source); + Server *s = Server::Find(source ? source : ""); + if (!ac) { /* for future use - start burst */ } else { @@ -720,9 +712,10 @@ int anope_event_burst(const char *source, int ac, const char **av) * finished bursting. If there was no source, then our uplink * server finished bursting. -GD */ - if (!s && serv_uplink) - s = serv_uplink; - finish_sync(s, 1); + if (!s) + s = Me->GetUplink(); + if (s) + s->Sync(true); } return MOD_CONT; } @@ -737,73 +730,71 @@ bool ChannelModeFlood::IsValid(const std::string &value) return false; } -void moduleAddIRCDMsgs() { - Message *m; - - /* now add the commands */ - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("SVSMODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("CS", anope_event_cs); addCoreMessage(IRCD,m); - m = createMessage("HS", anope_event_hs); addCoreMessage(IRCD,m); - m = createMessage("MS", anope_event_ms); addCoreMessage(IRCD,m); - m = createMessage("NS", anope_event_ns); addCoreMessage(IRCD,m); - m = createMessage("OS", anope_event_os); addCoreMessage(IRCD,m); - m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m); - m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m); - m = createMessage("BURST", anope_event_burst); addCoreMessage(IRCD,m); -} - -void moduleAddModes() +void moduleAddIRCDMsgs() +{ + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("SVSMODE", anope_event_mode); + Anope::AddMessage("CAPAB", anope_event_capab); + Anope::AddMessage("CS", anope_event_cs); + Anope::AddMessage("HS", anope_event_hs); + Anope::AddMessage("MS", anope_event_ms); + Anope::AddMessage("NS", anope_event_ns); + Anope::AddMessage("OS", anope_event_os); + Anope::AddMessage("SJOIN", anope_event_sjoin); + Anope::AddMessage("ERROR", anope_event_error); + Anope::AddMessage("BURST", anope_event_burst); +} + +static void AddModes() { /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A')); - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); + ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, "UMODE_SERV_ADMIN", 'A')); + ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R')); + ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER,"UMODE_OPER", 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd')); /* b/e/I */ ModeManager::AddChannelMode(new ChannelModeBan('b')); /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@')); /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); ModeManager::AddChannelMode(new ChannelModeFlood('f')); ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); ModeManager::AddChannelMode(new ChannelModeRegistered('r')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); ModeManager::AddChannelMode(new ChannelModeOper('O')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); } class ProtoBahamut : public Module @@ -824,7 +815,7 @@ class ProtoBahamut : public Module Capab.SetFlag(c[i]); moduleAddIRCDMsgs(); - moduleAddModes(); + AddModes(); pmodule_ircd_proto(&ircd_proto); diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.cpp index b5c55cfa8..09c329f0c 100644 --- a/src/protocol/inspircd11.c +++ b/src/protocol/inspircd11.cpp @@ -14,7 +14,7 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" #include "hashcomp.h" #ifndef _WIN32 @@ -40,7 +40,7 @@ IRCDVar myIrcd[] = { "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 1, /* Supports SGlines */ + 1, /* Supports SNlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ 4, /* Number of server args */ @@ -97,7 +97,7 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost) send_cmd(Config.s_OperServ, "CHGHOST %s %s", nick, vhost); } else - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!"); } int anope_event_idle(const char *source, int ac, const char **av) @@ -119,9 +119,9 @@ void inspircd_cmd_pass(const char *pass) class InspIRCdProto : public IRCDProto { - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - send_cmd(Config.s_OperServ, "GLINE %s@%s", ak->user, ak->host); + send_cmd(Config.s_OperServ, "GLINE %s", x->Mask.c_str()); } void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic) @@ -142,13 +142,13 @@ class InspIRCdProto : public IRCDProto } } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = ak->expires - time(NULL); + time_t timeleft = x->Expires - time(NULL); if (timeleft > 172800) timeleft = 172800; - send_cmd(Config.ServerName, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason); + send_cmd(Config.ServerName, "ADDLINE G %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str()); } void SendSVSKillInternal(BotInfo *source, User *user, const char *buf) @@ -204,7 +204,7 @@ class InspIRCdProto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(Server *server) { - send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->name, currentpass, server->hops, server->desc); + send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetDescription().c_str()); } /* JOIN */ @@ -214,19 +214,15 @@ class InspIRCdProto : public IRCDProto } /* UNSQLINE */ - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(Config.s_OperServ, "QLINE %s", user.c_str()); + send_cmd(Config.s_OperServ, "QLINE %s", x->Mask.c_str()); } /* SQLINE */ - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str()); + send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SQUIT */ @@ -248,11 +244,11 @@ class InspIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, ""); inspircd_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, ""); - SendServer(me_server); + SendServer(Me); send_cmd(NULL, "BURST"); - send_cmd(Config.ServerName, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build); + send_cmd(Config.ServerName, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build); } /* CHGIDENT */ @@ -264,7 +260,7 @@ class InspIRCdProto : public IRCDProto } send_cmd(Config.s_OperServ, "CHGIDENT %s %s", nick, vIdent); } else { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!"); } } @@ -281,21 +277,21 @@ class InspIRCdProto : public IRCDProto } /* UNSZLINE */ - void SendSZLineDel(SXLine *sx) + void SendSZLineDel(XLine *x) { - send_cmd(Config.s_OperServ, "ZLINE %s", sx->mask); + send_cmd(Config.s_OperServ, "ZLINE %s", x->Mask.c_str()); } /* SZLINE */ - void SendSZLine(SXLine *sx) + void SendSZLine(XLine *x) { - send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason); + send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SVSMODE +- */ void SendUnregisteredNick(User *u) { - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param) @@ -325,7 +321,7 @@ class InspIRCdProto : public IRCDProto u->Account()->Shrink("authenticationtoken"); u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf))); - u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->SetMode(NickServ, UMODE_REGISTERED); } } ircd_proto; @@ -823,10 +819,7 @@ int anope_event_chghost(const char *source, int ac, const char **av) /* EVENT: SERVER */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); - } - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); return MOD_CONT; } @@ -923,7 +916,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeInvite('I')); continue; default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); } } @@ -936,7 +929,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeKey('k')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); } } @@ -950,13 +943,13 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeFlood('f')); continue; case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); } } @@ -966,67 +959,67 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); continue; case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); continue; case 'A': - ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); continue; case 'V': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); } } } @@ -1040,19 +1033,19 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modes[t]) { case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '~')); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', '&')); continue; case 'o': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@')); continue; case 'h': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', '%')); continue; case 'v': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+')); continue; } } @@ -1083,13 +1076,13 @@ int anope_event_capab(const char *source, int ac, const char **av) return MOD_STOP; } if (!has_svsholdmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded."); } if (!has_chghostmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded."); } if (!has_chgidentmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded."); } ircd->svshold = has_svsholdmod; } @@ -1100,45 +1093,44 @@ int anope_event_capab(const char *source, int ac, const char **av) int anope_event_endburst(const char *source, int ac, const char **av) { - finish_sync(serv_uplink, 1); + Me->GetUplink()->Sync(true); return MOD_CONT; } -void moduleAddIRCDMsgs() { - Message *m; - - m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m); - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m); - m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m); - m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m); - m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m); - m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m); - m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m); - m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m); - m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m); - m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m); - m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m); - m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m); - m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m); +void moduleAddIRCDMsgs() +{ + Anope::AddMessage("ENDBURST", anope_event_endburst); + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("CAPAB",anope_event_capab); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("RSQUIT", anope_event_rsquit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("SVSMODE", anope_event_mode); + Anope::AddMessage("FHOST", anope_event_chghost); + Anope::AddMessage("CHGIDENT", anope_event_chgident); + Anope::AddMessage("FNAME", anope_event_chgname); + Anope::AddMessage("SETHOST", anope_event_sethost); + Anope::AddMessage("SETIDENT", anope_event_setident); + Anope::AddMessage("SETNAME", anope_event_setname); + Anope::AddMessage("FJOIN", anope_event_fjoin); + Anope::AddMessage("FMODE", anope_event_fmode); + Anope::AddMessage("FTOPIC", anope_event_ftopic); + Anope::AddMessage("OPERTYPE", anope_event_opertype); + Anope::AddMessage("IDLE", anope_event_idle); } bool ChannelModeFlood::IsValid(const std::string &value) @@ -1153,13 +1145,13 @@ bool ChannelModeFlood::IsValid(const std::string &value) static void AddModes() { - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g')); + ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x')); } class ProtoInspIRCd : public Module @@ -1171,7 +1163,7 @@ class ProtoInspIRCd : public Module this->SetVersion(VERSION_STRING); this->SetType(PROTOCOL); - pmodule_ircd_version("inspircdIRCd 1.1"); + pmodule_ircd_version("InspIRCd 1.1"); pmodule_ircd_var(myIrcd); pmodule_ircd_useTSMode(0); diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp index 4ad390f00..9a9f88fea 100644 --- a/src/protocol/inspircd12.cpp +++ b/src/protocol/inspircd12.cpp @@ -14,7 +14,7 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" #include "hashcomp.h" #ifndef _WIN32 @@ -40,7 +40,7 @@ IRCDVar myIrcd[] = { "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 0, /* Supports SGlines */ + 0, /* Supports SNlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ 4, /* Number of server args */ @@ -94,11 +94,11 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost) { if (has_chghostmod != 1) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!"); return; } - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "CHGHOST %s %s", nick, vhost); } @@ -123,10 +123,10 @@ void inspircd_cmd_pass(const char *pass) class InspIRCdProto : public IRCDProto { - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi->uid, "GLINE %s@%s", ak->user, ak->host); + BotInfo *bi = OperServ; + send_cmd(bi->uid, "GLINE %s", x->Mask.c_str()); } void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic) @@ -147,14 +147,14 @@ class InspIRCdProto : public IRCDProto } } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = ak->expires - time(NULL); - if (timeleft > 172800 || !ak->expires) + time_t timeleft = x->Expires - time(NULL); + if (timeleft > 172800 || !x->Expires) timeleft = 172800; - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason); + BotInfo *bi = OperServ; + send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str()); } void SendSVSKillInternal(BotInfo *source, User *user, const char *buf) @@ -209,7 +209,7 @@ class InspIRCdProto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %s %d %s :%s", server->name, currentpass, server->hops, server->suid, server->desc); + send_cmd(NULL, "SERVER %s %s %d %s :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str()); } /* JOIN */ @@ -219,19 +219,15 @@ class InspIRCdProto : public IRCDProto } /* UNSQLINE */ - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(TS6SID, "DELLINE Q %s", user.c_str()); + send_cmd(TS6SID, "DELLINE Q %s", x->Mask.c_str()); } /* SQLINE */ - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str()); + send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SQUIT */ @@ -252,11 +248,11 @@ class InspIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID); inspircd_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID); - SendServer(me_server); + SendServer(Me); send_cmd(TS6SID, "BURST"); - send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build); + send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build); } /* CHGIDENT */ @@ -264,11 +260,11 @@ class InspIRCdProto : public IRCDProto { if (has_chgidentmod == 0) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!"); } else { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "CHGIDENT %s %s", nick, vIdent); } } @@ -276,33 +272,33 @@ class InspIRCdProto : public IRCDProto /* SVSHOLD - set */ void SendSVSHold(const char *nick) { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "SVSHOLD %s %u :%s", nick, static_cast<unsigned>(Config.NSReleaseTimeout), "Being held for registered user"); } /* SVSHOLD - release */ void SendSVSHoldDel(const char *nick) { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "SVSHOLD %s", nick); } /* UNSZLINE */ - void SendSZLineDel(SXLine *sx) + void SendSZLineDel(XLine *x) { - send_cmd(TS6SID, "DELLINE Z %s", sx->mask); + send_cmd(TS6SID, "DELLINE Z %s", x->Mask.c_str()); } /* SZLINE */ - void SendSZLine(SXLine *sx) + void SendSZLine(XLine *x) { - send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason); + send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SVSMODE -r */ void SendUnregisteredNick(User *u) { - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param) @@ -362,7 +358,7 @@ class InspIRCdProto : public IRCDProto if (!u->Account()) return; - u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->SetMode(NickServ, UMODE_REGISTERED); } } ircd_proto; @@ -397,8 +393,8 @@ int anope_event_mode(const char *source, int ac, const char **av) users modes, we have to kludge this as it slightly breaks RFC1459 */ - User *u = find_byuid(source); - User *u2 = find_byuid(av[0]); + User *u = finduser(source); + User *u2 = finduser(av[0]); // This can happen with server-origin modes. if (u == NULL) @@ -554,7 +550,7 @@ int anope_event_fjoin(const char *source, int ac, const char **av) } buf.erase(buf.begin()); - User *u = find_byuid(buf); + User *u = finduser(buf); if (!u) { Alog(LOG_DEBUG) << "FJOIN for nonexistant user " << buf << " on " << c->name; @@ -646,7 +642,7 @@ int anope_event_topic(const char *source, int ac, const char **av) { Channel *c = findchan(av[0]); time_t topic_time = time(NULL); - User *u = find_byuid(source); + User *u = finduser(source); if (!c) { @@ -688,12 +684,10 @@ int anope_event_squit(const char *source, int ac, const char **av) int anope_event_rsquit(const char *source, int ac, const char **av) { /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */ - Server *s = findserver(servlist, av[0]); - if (!s) - s = findserver_uid(servlist, av[0]); + Server *s = Server::Find(av[0]); if (s && s->HasFlag(SERVER_JUPED)) { - send_cmd(TS6SID, "SQUIT %s :%s", s->suid, ac > 1 ? av[1] : ""); + send_cmd(TS6SID, "SQUIT %s :%s", s->GetSID().c_str(), ac > 1 ? av[1] : ""); } do_squit(source, ac, av); @@ -710,7 +704,7 @@ int anope_event_quit(const char *source, int ac, const char **av) int anope_event_kill(const char *source, int ac, const char **av) { - User *u = find_byuid(av[0]); + User *u = finduser(av[0]); BotInfo *bi = findbot(av[0]); m_kill(u ? u->nick.c_str() : (bi ? bi->nick : av[0]), av[1]); return MOD_CONT; @@ -837,7 +831,7 @@ int anope_event_uid(const char *source, int ac, const char **av) User *user; NickAlias *na; struct in_addr addy; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); uint32 *ad = reinterpret_cast<uint32 *>(&addy); int ts = strtoul(av[1], NULL, 10); @@ -846,11 +840,11 @@ int anope_event_uid(const char *source, int ac, const char **av) user = prev_u_intro; prev_u_intro = NULL; if (user) na = findnick(user->nick); - if (user && user->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != user->Account())) + if (user && !user->server->IsSynced() && (!na || na->nc != user->Account())) { validate_user(user); if (user->HasMode(UMODE_REGISTERED)) - user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + user->RemoveMode(NickServ, UMODE_REGISTERED); } user = NULL; @@ -858,14 +852,14 @@ int anope_event_uid(const char *source, int ac, const char **av) user = do_nick("", av[2], /* nick */ av[5], /* username */ av[3], /* realhost */ - s->name, /* server */ + s->GetName().c_str(), /* server */ av[ac - 1], /* realname */ ts, htonl(*ad), av[4], av[0]); if (user) { UserSetInternalModes(user, 1, &av[8]); user->SetCloakedHost(av[4]); - if (user->server->sync == SSYNC_IN_PROGRESS) + if (!user->server->IsSynced()) { prev_u_intro = user; } @@ -903,24 +897,17 @@ int anope_event_chghost(const char *source, int ac, const char **av) */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[2], "0")) - { - uplink = sstrdup(av[0]); - } - do_server(source, av[0], av[2], av[4], av[3]); + do_server(source, av[0], atoi(av[2]), av[4], av[3]); return MOD_CONT; } int anope_event_privmsg(const char *source, int ac, const char **av) { - User *u = find_byuid(source); - BotInfo *bi = findbot(av[0]); - - if (!u) + if (!finduser(source)) return MOD_CONT; // likely a message from a server, which can happen. - m_privmsg(u->nick.c_str(), bi ? bi->nick: av[0], av[1]); + m_privmsg(source, av[0], av[1]); return MOD_CONT; } @@ -944,7 +931,7 @@ int anope_event_metadata(const char *source, int ac, const char **av) return MOD_CONT; else if (!strcmp(av[1], "accountname")) { - if ((u = find_byuid(av[0]))) + if ((u = finduser(av[0]))) { /* Identify the user for this account - Adam */ u->AutoID(av[2]); @@ -1026,14 +1013,14 @@ int anope_event_capab(const char *source, int ac, const char **av) continue; /* InspIRCd sends q and a here if they have no prefixes */ case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '@')); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , 'a', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , "CMODE_PROTECT", 'a', '@')); continue; // XXX list modes needs a bit of a rewrite, we need to be able to support +g here default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); } } @@ -1046,7 +1033,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeKey('k')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); } } @@ -1056,25 +1043,25 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'F': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, "CMODE_NICKFLOOD", 'F', true)); continue; case 'J': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, "CMODE_NOREJOIN", 'J', true)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true)); continue; case 'f': ModeManager::AddChannelMode(new ChannelModeFlood('f', true)); continue; case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true)); continue; case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); } } @@ -1084,79 +1071,79 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'A': - ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A')); continue; case 'B': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, 'B')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, "CMODE_BLOCKCAPS", 'B')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); continue; case 'D': - ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, 'D')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, "CMODE_DELAYEDJOIN", 'D')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); continue; case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); continue; case 'P': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, "CMODE_PERM", 'P')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); continue; case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); continue; case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); continue; case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); } } } @@ -1173,64 +1160,64 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'h': - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); + ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h')); continue; case 's': - ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S')); + ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S')); continue; case 'B': - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); + ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B')); continue; case 'G': - ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G')); + ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G')); continue; case 'H': - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); + ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H')); continue; case 'I': - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'I')); + ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'I')); continue; case 'Q': - ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, 'Q')); + ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, "UMODE_HIDDEN", 'Q')); continue; case 'R': - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); + ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R')); continue; case 'S': - ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S')); + ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S')); continue; case 'W': - ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W')); + ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W')); continue; case 'c': - ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'c')); + ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, "UMODE_COMMONCHANS", 'c')); continue; case 'g': - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); + ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g')); continue; case 'i': - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); continue; case 'k': - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'k')); + ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'k')); continue; case 'o': - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o')); continue; case 'r': - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); + ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r')); continue; case 'w': - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); continue; case 'x': - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x')); continue; case 'd': - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); + ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd')); continue; default: - ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t])); + ModeManager::AddUserMode(new UserMode(UMODE_END, "", modebuf[t])); } } } @@ -1245,19 +1232,19 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modes[t]) { case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', chars[t])); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', chars[t])); continue; case 'o': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', chars[t])); continue; case 'h': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', chars[t])); continue; case 'v': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', chars[t])); continue; } } @@ -1288,13 +1275,13 @@ int anope_event_capab(const char *source, int ac, const char **av) return MOD_STOP; } if (!has_svsholdmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded."); } if (!has_chghostmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded."); } if (!has_chgidentmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded."); } ircd->svshold = has_svsholdmod; } @@ -1308,7 +1295,8 @@ int anope_event_endburst(const char *source, int ac, const char **av) { NickAlias *na; User *u = prev_u_intro; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); + if (!s) { throw new CoreException("Got ENDBURST without a source"); @@ -1318,56 +1306,55 @@ int anope_event_endburst(const char *source, int ac, const char **av) * If not, validate the user. ~ Viper*/ prev_u_intro = NULL; if (u) na = findnick(u->nick); - if (u && u->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != u->Account())) + if (u && !u->server->IsSynced() && (!na || na->nc != u->Account())) { validate_user(u); if (u->HasMode(UMODE_REGISTERED)) - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } - Alog() << "Processed ENDBURST for " << s->name; + Alog() << "Processed ENDBURST for " << s->GetName(); - finish_sync(s, 1); + s->Sync(true); return MOD_CONT; } -void moduleAddIRCDMsgs() { - Message *m; - - m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m); - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("UID", anope_event_uid); addCoreMessage(IRCD,m); - m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("TIME", anope_event_time); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m); - m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m); - m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m); - m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m); - m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m); - m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m); - m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m); - m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m); - m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m); - m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m); - m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m); - m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m); - m = createMessage("METADATA", anope_event_metadata); addCoreMessage(IRCD,m); +void moduleAddIRCDMsgs() +{ + Anope::AddMessage("ENDBURST", anope_event_endburst); + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("UID", anope_event_uid); + Anope::AddMessage("CAPAB", anope_event_capab); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("TIME", anope_event_time); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("RSQUIT", anope_event_rsquit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("SVSMODE", anope_event_mode); + Anope::AddMessage("FHOST", anope_event_chghost); + Anope::AddMessage("CHGIDENT", anope_event_chgident); + Anope::AddMessage("FNAME", anope_event_chgname); + Anope::AddMessage("SETHOST", anope_event_sethost); + Anope::AddMessage("SETIDENT", anope_event_setident); + Anope::AddMessage("SETNAME", anope_event_setname); + Anope::AddMessage("FJOIN", anope_event_fjoin); + Anope::AddMessage("FMODE", anope_event_fmode); + Anope::AddMessage("FTOPIC", anope_event_ftopic); + Anope::AddMessage("OPERTYPE", anope_event_opertype); + Anope::AddMessage("IDLE", anope_event_idle); + Anope::AddMessage("METADATA", anope_event_metadata); } bool ChannelModeFlood::IsValid(const std::string &value) @@ -1413,7 +1400,7 @@ class ProtoInspIRCd : public Module /* InspIRCd 1.2 doesn't set -r on nick change, remove -r here. Note that if we have to set +r later * this will cancel out this -r, resulting in no mode changes. */ - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } }; diff --git a/src/protocol/inspircd20.cpp b/src/protocol/inspircd20.cpp index 4b37e8c1c..4d333658c 100644 --- a/src/protocol/inspircd20.cpp +++ b/src/protocol/inspircd20.cpp @@ -1,4 +1,4 @@ -/* inspircd 1.2 functions +/* Inspircd 2.0 functions * * (C) 2003-2010 Anope Team * Contact us at team@anope.org @@ -14,7 +14,7 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" #include "hashcomp.h" #ifndef _WIN32 @@ -40,7 +40,7 @@ IRCDVar myIrcd[] = { "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 0, /* Supports SGlines */ + 0, /* Supports SNlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ 4, /* Number of server args */ @@ -93,11 +93,11 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost) { if (has_chghostmod != 1) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!"); return; } - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "CHGHOST %s %s", nick, vhost); } @@ -122,10 +122,10 @@ void inspircd_cmd_pass(const char *pass) class InspIRCdProto : public IRCDProto { - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi->uid, "GLINE %s@%s", ak->user, ak->host); + BotInfo *bi = OperServ; + send_cmd(bi->uid, "GLINE %s", x->Mask.c_str()); } void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic) @@ -146,14 +146,14 @@ class InspIRCdProto : public IRCDProto } } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = ak->expires - time(NULL); - if (timeleft > 172800 || !ak->expires) + time_t timeleft = x->Expires - time(NULL); + if (timeleft > 172800 || !x->Expires) timeleft = 172800; - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason); + BotInfo *bi = OperServ; + send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str()); } void SendSVSKillInternal(BotInfo *source, User *user, const char *buf) @@ -208,7 +208,7 @@ class InspIRCdProto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %s %d %s :%s", server->name, currentpass, server->hops, server->suid, server->desc); + send_cmd(NULL, "SERVER %s %s %d %s :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str()); } /* JOIN */ @@ -218,19 +218,15 @@ class InspIRCdProto : public IRCDProto } /* UNSQLINE */ - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(TS6SID, "DELLINE Q %s", user.c_str()); + send_cmd(TS6SID, "DELLINE Q %s", x->Mask.c_str()); } /* SQLINE */ - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str()); + send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SQUIT */ @@ -251,11 +247,11 @@ class InspIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID); inspircd_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID); - SendServer(me_server); + SendServer(Me); send_cmd(TS6SID, "BURST"); - send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build); + send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build); } /* CHGIDENT */ @@ -263,11 +259,11 @@ class InspIRCdProto : public IRCDProto { if (has_chgidentmod == 0) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!"); + ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!"); } else { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "CHGIDENT %s %s", nick, vIdent); } } @@ -275,33 +271,33 @@ class InspIRCdProto : public IRCDProto /* SVSHOLD - set */ void SendSVSHold(const char *nick) { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "SVSHOLD %s %u :%s", nick, static_cast<unsigned>(Config.NSReleaseTimeout), "Being held for registered user"); } /* SVSHOLD - release */ void SendSVSHoldDel(const char *nick) { - BotInfo *bi = findbot(Config.s_OperServ); + BotInfo *bi = OperServ; send_cmd(bi->uid, "SVSHOLD %s", nick); } /* UNSZLINE */ - void SendSZLineDel(SXLine *sx) + void SendSZLineDel(XLine *x) { - send_cmd(TS6SID, "DELLINE Z %s", sx->mask); + send_cmd(TS6SID, "DELLINE Z %s", x->Mask.c_str()); } /* SZLINE */ - void SendSZLine(SXLine *sx) + void SendSZLine(XLine *x) { - send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason); + send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SVSMODE -r */ void SendUnregisteredNick(User *u) { - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param) @@ -361,7 +357,7 @@ class InspIRCdProto : public IRCDProto if (!u->Account()) return; - u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->SetMode(NickServ, UMODE_REGISTERED); } } ircd_proto; @@ -396,8 +392,8 @@ int anope_event_mode(const char *source, int ac, const char **av) users modes, we have to kludge this as it slightly breaks RFC1459 */ - User *u = find_byuid(source); - User *u2 = find_byuid(av[0]); + User *u = finduser(source); + User *u2 = finduser(av[0]); // This can happen with server-origin modes. if (u == NULL) @@ -553,7 +549,7 @@ int anope_event_fjoin(const char *source, int ac, const char **av) } buf.erase(buf.begin()); - User *u = find_byuid(buf); + User *u = finduser(buf); if (!u) { Alog(LOG_DEBUG) << "FJOIN for nonexistant user " << buf << " on " << c->name; @@ -645,7 +641,7 @@ int anope_event_topic(const char *source, int ac, const char **av) { Channel *c = findchan(av[0]); time_t topic_time = time(NULL); - User *u = find_byuid(source); + User *u = finduser(source); if (!c) { @@ -687,12 +683,10 @@ int anope_event_squit(const char *source, int ac, const char **av) int anope_event_rsquit(const char *source, int ac, const char **av) { /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */ - Server *s = findserver(servlist, av[0]); - if (!s) - s = findserver_uid(servlist, av[0]); + Server *s = Server::Find(av[0]); if (s && s->HasFlag(SERVER_JUPED)) { - send_cmd(TS6SID, "SQUIT %s :%s", s->suid, ac > 1 ? av[1] : ""); + send_cmd(TS6SID, "SQUIT %s :%s", s->GetSID().c_str(), ac > 1 ? av[1] : ""); } do_squit(source, ac, av); @@ -709,7 +703,7 @@ int anope_event_quit(const char *source, int ac, const char **av) int anope_event_kill(const char *source, int ac, const char **av) { - User *u = find_byuid(av[0]); + User *u = finduser(av[0]); BotInfo *bi = findbot(av[0]); m_kill(u ? u->nick.c_str() : (bi ? bi->nick : av[0]), av[1]); return MOD_CONT; @@ -836,7 +830,7 @@ int anope_event_uid(const char *source, int ac, const char **av) User *user; NickAlias *na; struct in_addr addy; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); uint32 *ad = reinterpret_cast<uint32 *>(&addy); int ts = strtoul(av[1], NULL, 10); @@ -845,11 +839,11 @@ int anope_event_uid(const char *source, int ac, const char **av) user = prev_u_intro; prev_u_intro = NULL; if (user) na = findnick(user->nick); - if (user && user->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != user->Account())) + if (user && !user->server->IsSynced() && (!na || na->nc != user->Account())) { validate_user(user); if (user->HasMode(UMODE_REGISTERED)) - user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + user->RemoveMode(NickServ, UMODE_REGISTERED); } user = NULL; @@ -857,14 +851,14 @@ int anope_event_uid(const char *source, int ac, const char **av) user = do_nick("", av[2], /* nick */ av[5], /* username */ av[3], /* realhost */ - s->name, /* server */ + s->GetName().c_str(), /* server */ av[ac - 1], /* realname */ ts, htonl(*ad), av[4], av[0]); if (user) { UserSetInternalModes(user, 1, &av[8]); user->SetCloakedHost(av[4]); - if (user->server->sync == SSYNC_IN_PROGRESS) + if (!user->server->IsSynced()) { prev_u_intro = user; } @@ -902,24 +896,17 @@ int anope_event_chghost(const char *source, int ac, const char **av) */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[2], "0")) - { - uplink = sstrdup(av[0]); - } - do_server(source, av[0], av[2], av[4], av[3]); + do_server(source, av[0], atoi(av[2]), av[4], av[3]); return MOD_CONT; } int anope_event_privmsg(const char *source, int ac, const char **av) { - User *u = find_byuid(source); - BotInfo *bi = findbot(av[0]); - - if (!u) + if (!finduser(source)) return MOD_CONT; // likely a message from a server, which can happen. - m_privmsg(u->nick.c_str(), bi ? bi->nick: av[0], av[1]); + m_privmsg(source, av[0], av[1]); return MOD_CONT; } @@ -943,7 +930,7 @@ int anope_event_metadata(const char *source, int ac, const char **av) return MOD_CONT; else if (!strcmp(av[1], "accountname")) { - if ((u = find_byuid(av[0]))) + if ((u = finduser(av[0]))) { /* Identify the user for this account - Adam */ u->AutoID(av[2]); @@ -1025,14 +1012,14 @@ int anope_event_capab(const char *source, int ac, const char **av) continue; /* InspIRCd sends q and a here if they have no prefixes */ case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '@')); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , 'a', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , "CMODE_PROTECT", 'a', '@')); continue; // XXX list modes needs a bit of a rewrite, we need to be able to support +g here default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); } } @@ -1045,7 +1032,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeKey('k')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); } } @@ -1055,25 +1042,25 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'F': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, "CMODE_NICKFLOOD", 'F', true)); continue; case 'J': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, "CMODE_NOREJOIN", 'J', true)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true)); continue; case 'f': ModeManager::AddChannelMode(new ChannelModeFlood('f', true)); continue; case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true)); continue; case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); } } @@ -1083,79 +1070,79 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'A': - ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A')); continue; case 'B': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, 'B')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, "CMODE_BLOCKCAPS", 'B')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); continue; case 'D': - ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, 'D')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, "CMODE_DELAYEDJOIN", 'D')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); continue; case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); continue; case 'P': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, "CMODE_PERM", 'P')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); continue; case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); continue; case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); continue; case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); } } } @@ -1172,64 +1159,64 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'h': - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); + ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h')); continue; case 's': - ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S')); + ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S')); continue; case 'B': - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); + ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B')); continue; case 'G': - ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G')); + ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G')); continue; case 'H': - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); + ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H')); continue; case 'I': - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'I')); + ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'I')); continue; case 'Q': - ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, 'Q')); + ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, "UMODE_HIDDEN", 'Q')); continue; case 'R': - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); + ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R')); continue; case 'S': - ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S')); + ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S')); continue; case 'W': - ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W')); + ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W')); continue; case 'c': - ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'c')); + ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, "UMODE_COMMONCHANS", 'c')); continue; case 'g': - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); + ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g')); continue; case 'i': - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); continue; case 'k': - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'k')); + ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'k')); continue; case 'o': - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o')); continue; case 'r': - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); + ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r')); continue; case 'w': - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); continue; case 'x': - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x')); continue; case 'd': - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); + ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd')); continue; default: - ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t])); + ModeManager::AddUserMode(new UserMode(UMODE_END, "", modebuf[t])); } } } @@ -1244,19 +1231,19 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modes[t]) { case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', chars[t])); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', chars[t])); continue; case 'o': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', chars[t])); continue; case 'h': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', chars[t])); continue; case 'v': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t])); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', chars[t])); continue; } } @@ -1287,13 +1274,13 @@ int anope_event_capab(const char *source, int ac, const char **av) return MOD_STOP; } if (!has_svsholdmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded."); } if (!has_chghostmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded."); } if (!has_chgidentmod) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded."); + ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded."); } ircd->svshold = has_svsholdmod; } @@ -1307,7 +1294,8 @@ int anope_event_endburst(const char *source, int ac, const char **av) { NickAlias *na; User *u = prev_u_intro; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); + if (!s) { throw new CoreException("Got ENDBURST without a source"); @@ -1317,56 +1305,55 @@ int anope_event_endburst(const char *source, int ac, const char **av) * If not, validate the user. ~ Viper*/ prev_u_intro = NULL; if (u) na = findnick(u->nick); - if (u && u->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != u->Account())) + if (u && !u->server->IsSynced() && (!na || na->nc != u->Account())) { validate_user(u); if (u->HasMode(UMODE_REGISTERED)) - u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + u->RemoveMode(NickServ, UMODE_REGISTERED); } - Alog() << "Processed ENDBURST for " << s->name; + Alog() << "Processed ENDBURST for " << s->GetName(); - finish_sync(s, 1); + s->Sync(true); return MOD_CONT; } -void moduleAddIRCDMsgs() { - Message *m; - - m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m); - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("UID", anope_event_uid); addCoreMessage(IRCD,m); - m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("TIME", anope_event_time); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m); - m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m); - m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m); - m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m); - m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m); - m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m); - m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m); - m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m); - m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m); - m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m); - m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m); - m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m); - m = createMessage("METADATA", anope_event_metadata); addCoreMessage(IRCD,m); +void moduleAddIRCDMsgs() +{ + Anope::AddMessage("ENDBURST", anope_event_endburst); + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("UID", anope_event_uid); + Anope::AddMessage("CAPAB", anope_event_capab); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("TIME", anope_event_time); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("RSQUIT", anope_event_rsquit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("SVSMODE", anope_event_mode); + Anope::AddMessage("FHOST", anope_event_chghost); + Anope::AddMessage("CHGIDENT", anope_event_chgident); + Anope::AddMessage("FNAME", anope_event_chgname); + Anope::AddMessage("SETHOST", anope_event_sethost); + Anope::AddMessage("SETIDENT", anope_event_setident); + Anope::AddMessage("SETNAME", anope_event_setname); + Anope::AddMessage("FJOIN", anope_event_fjoin); + Anope::AddMessage("FMODE", anope_event_fmode); + Anope::AddMessage("FTOPIC", anope_event_ftopic); + Anope::AddMessage("OPERTYPE", anope_event_opertype); + Anope::AddMessage("IDLE", anope_event_idle); + Anope::AddMessage("METADATA", anope_event_metadata); } bool ChannelModeFlood::IsValid(const std::string &value) @@ -1409,7 +1396,6 @@ class ProtoInspIRCd : public Module void OnUserNickChange(User *u, const std::string &) { - /* InspIRCd 2.0 removes r on nick change and doesn't tell services, even though it tells the user */ u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); } }; diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.cpp index 8d0a84826..339113e33 100644 --- a/src/protocol/ratbox.c +++ b/src/protocol/ratbox.cpp @@ -12,7 +12,9 @@ */ #include "services.h" -#include "pseudo.h" +#include "modules.h" + +static char *TS6UPLINK = NULL; // XXX is this needed? IRCDVar myIrcd[] = { {"Ratbox 2.0+", /* ircd name */ @@ -21,7 +23,7 @@ IRCDVar myIrcd[] = { "+o", /* Channel Umode used by Botserv bots */ 0, /* SVSNICK */ 0, /* Vhost */ - 1, /* Supports SGlines */ + 1, /* Supports SNlines */ 1, /* Supports SQlines */ 0, /* Supports SZlines */ 3, /* Number of server args */ @@ -134,36 +136,32 @@ class RatboxProto : public IRCDTS6Proto send_cmd(TS6SID, "OPERWALL :%s", buf); } - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(TS6SID, "RESV * %s :%s", mask.c_str(), reason.c_str()); + send_cmd(TS6SID, "RESV * %s :%s", x->Mask.c_str(), x->Reason.c_str()); } - void SendSGLineDel(SXLine *sx) + void SendSGLineDel(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", sx->mask); + BotInfo *bi = OperServ; + send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", x->Mask.c_str()); } - void SendSGLine(SXLine *sx) + void SendSGLine(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", sx->mask, sx->reason); + BotInfo *bi = OperServ; + send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", x->Mask.c_str(), x->Reason.c_str()); } - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", ak->user, ak->host); + BotInfo *bi = OperServ; + send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", x->GetUser().c_str(), x->GetHost().c_str()); } - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(TS6SID, "UNRESV * %s", user.c_str()); + send_cmd(TS6SID, "UNRESV * %s", x->Mask.c_str()); } void SendJoin(BotInfo *user, const char *channel, time_t chantime) @@ -171,10 +169,10 @@ class RatboxProto : public IRCDTS6Proto send_cmd(NULL, "SJOIN %ld %s + :%s", static_cast<long>(chantime), channel, user->uid.c_str()); } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { - BotInfo *bi = findbot(Config.s_OperServ); - send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(ak->expires - time(NULL)), ak->user, ak->host, ak->reason); + BotInfo *bi = OperServ; + send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(x->Expires - time(NULL)), x->GetUser().c_str(), x->GetHost().c_str(), x->Reason.c_str()); } void SendSVSKillInternal(BotInfo *source, User *user, const char *buf) @@ -190,16 +188,16 @@ class RatboxProto : public IRCDTS6Proto /* SERVER name hop descript */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID); ratbox_cmd_pass(uplink_server->password); ratbox_cmd_capab(); /* Make myself known to myself in the serverlist */ - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID); - SendServer(me_server); + SendServer(Me); ratbox_cmd_svinfo(); } @@ -380,7 +378,7 @@ int anope_event_sjoin(const char *source, int ac, const char **av) Status.push_back(cm); } - User *u = find_byuid(buf); + User *u = finduser(buf); if (!u) { Alog(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << c->name; @@ -457,14 +455,13 @@ int anope_event_sjoin(const char *source, int ac, const char **av) */ int anope_event_nick(const char *source, int ac, const char **av) { - Server *s; User *user; if (ac == 9) { - s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); /* Source is always the server */ - user = do_nick("", av[0], av[4], av[5], s->name, av[8], + user = do_nick("", av[0], av[4], av[5], s->GetName().c_str(), av[8], strtoul(av[2], NULL, 10), 0, "*", av[7]); if (user) { @@ -510,7 +507,7 @@ int anope_event_topic(const char *source, int ac, const char **av) if (ac > 1 && *av[1]) c->topic = sstrdup(av[1]); - u = find_byuid(source); + u = finduser(source); c->topic_setter = u ? u->nick : source; c->topic_time = topic_time; @@ -593,7 +590,7 @@ int anope_event_away(const char *source, int ac, const char **av) { User *u = NULL; - u = find_byuid(source); + u = finduser(source); m_away(u ? u->nick.c_str() : source, (ac ? av[0] : NULL)); return MOD_CONT; } @@ -645,7 +642,7 @@ int anope_event_privmsg(const char *source, int ac, const char **av) return MOD_CONT; } - u = find_byuid(source); + u = finduser(source); bi = findbot(av[0]); // XXX: this is really the same as charybdis m_privmsg(source, av[0], av[1]); @@ -660,7 +657,7 @@ int anope_event_part(const char *source, int ac, const char **av) return MOD_CONT; } - u = find_byuid(source); + u = finduser(source); do_part(u ? u->nick.c_str() : source, ac, av); return MOD_CONT; @@ -681,27 +678,24 @@ int anope_event_whois(const char *source, int ac, const char **av) int anope_event_server(const char *source, int ac, const char **av) { if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); if (TS6UPLINK) { - do_server(source, av[0], av[1], av[2], TS6UPLINK); + do_server(source, av[0], atoi(av[1]), av[2], TS6UPLINK); } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } return MOD_CONT; } int anope_event_sid(const char *source, int ac, const char **av) { - Server *s; - /* :42X SID trystan.nomadirc.net 2 43X :ircd-ratbox test server */ - s = findserver_uid(servlist, source); + Server *s = Server::Find(source); - do_server(s->name, av[0], av[1], av[3], av[2]); + do_server(s->GetName(), av[0], atoi(av[1]), av[3], av[2]); return MOD_CONT; } @@ -721,7 +715,7 @@ int anope_event_quit(const char *source, int ac, const char **av) return MOD_CONT; } - u = find_byuid(source); + u = finduser(source); do_quit(u ? u->nick.c_str() : source, ac, av); return MOD_CONT; @@ -738,8 +732,8 @@ int anope_event_mode(const char *source, int ac, const char **av) if (*av[0] == '#' || *av[0] == '&') { do_cmode(source, ac, av); } else { - u = find_byuid(source); - u2 = find_byuid(av[0]); + u = finduser(source); + u2 = finduser(av[0]); av[0] = u2->nick.c_str(); do_umode(u->nick.c_str(), ac, av); } @@ -813,43 +807,41 @@ int anope_event_error(const char *source, int ac, const char **av) void moduleAddIRCDMsgs() { - Message *m; - - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("TMODE", anope_event_tmode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("BMASK", anope_event_bmask); addCoreMessage(IRCD,m); - m = createMessage("UID", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PASS", anope_event_pass); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("TB", anope_event_tburst); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m); - m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m); - m = createMessage("SID", anope_event_sid); addCoreMessage(IRCD,m); + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("TMODE", anope_event_tmode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("BMASK", anope_event_bmask); + Anope::AddMessage("UID", anope_event_nick); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("PASS", anope_event_pass); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage("TB", anope_event_tburst); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("CAPAB", anope_event_capab); + Anope::AddMessage("SJOIN", anope_event_sjoin); + Anope::AddMessage("ERROR", anope_event_error); + Anope::AddMessage("SID", anope_event_sid); } -void moduleAddModes() +static void AddModes() { /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); /* b/e/I */ ModeManager::AddChannelMode(new ChannelModeBan('b')); @@ -857,18 +849,18 @@ void moduleAddModes() ModeManager::AddChannelMode(new ChannelModeInvite('I')); /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@')); /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); } class ProtoRatbox : public Module @@ -892,7 +884,7 @@ class ProtoRatbox : public Module for (unsigned i = 0; i < 5; ++i) Capab.SetFlag(c[i]); - moduleAddModes(); + AddModes(); pmodule_ircd_proto(&ircd_proto); moduleAddIRCDMsgs(); diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.cpp index 3564fecd6..65ee9d3e2 100644 --- a/src/protocol/unreal32.c +++ b/src/protocol/unreal32.cpp @@ -14,7 +14,7 @@ /*************************************************************************/ #include "services.h" -#include "pseudo.h" +#include "modules.h" IRCDVar myIrcd[] = { {"UnrealIRCd 3.2.x", /* ircd name */ @@ -23,7 +23,7 @@ IRCDVar myIrcd[] = { "+ao", /* Channel Umode used by Botserv bots */ 1, /* SVSNICK */ 1, /* Vhost */ - 1, /* Supports SGlines */ + 1, /* Supports SNlines */ 1, /* Supports SQlines */ 1, /* Supports SZlines */ 3, /* Number of server args */ @@ -133,9 +133,9 @@ class UnrealIRCdProto : public IRCDProto send_cmd(NULL, "f %s %s", server, set ? "+" : "-"); } - void SendAkillDel(Akill *ak) + void SendAkillDel(XLine *x) { - send_cmd(NULL, "BD - G %s %s %s", ak->user, ak->host, Config.s_OperServ); + send_cmd(NULL, "BD - G %s %s %s", x->GetUser().c_str(), x->GetHost().c_str(), Config.s_OperServ); } void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic) @@ -145,7 +145,7 @@ class UnrealIRCdProto : public IRCDProto void SendVhostDel(User *u) { - BotInfo *bi = findbot(Config.s_HostServ); + BotInfo *bi = HostServ; u->RemoveMode(bi, UMODE_CLOAK); u->RemoveMode(bi, UMODE_VHOST); ModeManager::ProcessModes(); @@ -153,12 +153,12 @@ class UnrealIRCdProto : public IRCDProto ModeManager::ProcessModes(); } - void SendAkill(Akill *ak) + void SendAkill(XLine *x) { // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = ak->expires - time(NULL); + time_t timeleft = x->Expires - time(NULL); if (timeleft > 172800) timeleft = 172800; - send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL) + timeleft), static_cast<long>(ak->expires), ak->reason); + send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL) + timeleft), static_cast<long>(x->Expires), x->Reason.c_str()); } void SendSVSKillInternal(BotInfo *source, User *user, const char *buf) @@ -216,9 +216,9 @@ class UnrealIRCdProto : public IRCDProto void SendServer(Server *server) { if (Config.Numeric) - send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->name, server->hops, Config.Numeric, server->desc); + send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->GetName().c_str(), server->GetHops(), Config.Numeric, server->GetDescription().c_str()); else - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } /* JOIN */ @@ -228,31 +228,21 @@ class UnrealIRCdProto : public IRCDProto } /* unsqline - ** parv[0] = sender - ** parv[1] = nickmask */ - void SendSQLineDel(const std::string &user) + void SendSQLineDel(XLine *x) { - if (user.empty()) - return; - send_cmd(NULL, "d %s", user.c_str()); + send_cmd(NULL, "d %s", x->Mask.c_str()); } /* SQLINE */ /* - ** parv[0] = sender - ** parv[1] = nickmask - ** parv[2] = reason - ** ** - Unreal will translate this to TKL for us ** */ - void SendSQLine(const std::string &mask, const std::string &reason) + void SendSQLine(XLine *x) { - if (mask.empty() || reason.empty()) - return; - send_cmd(NULL, "c %s :%s", mask.c_str(), reason.c_str()); + send_cmd(NULL, "c %s :%s", x->Mask.c_str(), x->Reason.c_str()); } /* @@ -286,10 +276,10 @@ class UnrealIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, (Config.Numeric ? Config.Numeric : "")); unreal_cmd_capab(); unreal_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, (Config.Numeric ? Config.Numeric : "")); - SendServer(me_server); + SendServer(Me); } /* SVSHOLD - set */ @@ -309,33 +299,33 @@ class UnrealIRCdProto : public IRCDProto /* * SVSNLINE - :realname mask */ - void SendSGLineDel(SXLine *sx) + void SendSGLineDel(XLine *x) { - send_cmd(NULL, "BR - :%s", sx->mask); + send_cmd(NULL, "BR - :%s", x->Mask.c_str()); } /* UNSZLINE */ - void SendSZLineDel(SXLine *sx) + void SendSZLineDel(XLine *x) { - send_cmd(NULL, "BD - Z * %s %s", sx->mask, Config.s_OperServ); + send_cmd(NULL, "BD - Z * %s %s", x->Mask.c_str(), Config.s_OperServ); } /* SZLINE */ - void SendSZLine(SXLine *sx) + void SendSZLine(XLine *x) { - send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", sx->mask, sx->by, static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), sx->reason); + send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), x->Reason.c_str()); } /* SGLINE */ /* * SVSNLINE + reason_where_is_space :realname mask with spaces */ - void SendSGLine(SXLine *sx) + void SendSGLine(XLine *x) { char edited_reason[BUFSIZE]; - strlcpy(edited_reason, sx->reason, BUFSIZE); + strlcpy(edited_reason, x->Reason.c_str(), BUFSIZE); strnrepl(edited_reason, BUFSIZE, " ", "_"); - send_cmd(NULL, "BR + %s :%s", edited_reason, sx->mask); + send_cmd(NULL, "BR + %s :%s", edited_reason, x->Mask.c_str()); } /* SVSMODE -b */ @@ -418,14 +408,14 @@ class UnrealIRCdProto : public IRCDProto u->Account()->Shrink("authenticationtoken"); u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf))); - BotInfo *bi = findbot(Config.s_NickServ); + BotInfo *bi = NickServ; u->SetMode(bi, UMODE_REGISTERED); ircdproto->SendMode(bi, u, "+d %s", svidbuf); } void SendUnregisteredNick(User *u) { - BotInfo *bi = findbot(Config.s_NickServ); + BotInfo *bi = NickServ; u->RemoveMode(bi, UMODE_REGISTERED); ircdproto->SendMode(bi, u, "+d 1"); } @@ -462,7 +452,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeInvite('I')); continue; default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t])); } } @@ -478,10 +468,10 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeFlood('f')); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L')); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t])); } } @@ -491,13 +481,13 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true)); continue; case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true)); } } @@ -507,31 +497,31 @@ int anope_event_capab(const char *source, int ac, const char **av) switch (modebuf[t]) { case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't')); continue; case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); @@ -540,40 +530,40 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeAdmin('A')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K')); continue; case 'V': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S')); continue; case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M')); continue; case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t])); } } } @@ -604,9 +594,9 @@ int anope_event_ping(const char *source, int ac, const char **av) */ int anope_event_pong(const char *source, int ac, const char **av) { - Server *s = findserver(servlist, source); - if (s && !is_sync(s)) - finish_sync(s, 0); + Server *s = Server::Find(source); + if (s && !s->IsSynced()) + s->Sync(false); return MOD_CONT; } @@ -701,7 +691,7 @@ int anope_event_mode(const char *source, int ac, const char **av) /* This is used to strip the TS from the end of the mode stirng */ int anope_event_gmode(const char *source, int ac, const char **av) { - if (findserver(servlist, source)) + if (Server::Find(source)) --ac; return anope_event_mode(source, ac, av); } @@ -966,16 +956,15 @@ int anope_event_server(const char *source, int ac, const char **av) char *upnumeric; if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); vl = myStrGetToken(av[2], ' ', 0); upnumeric = myStrGetToken(vl, '-', 2); desc = myStrGetTokenRemainder(av[2], ' ', 1); - do_server(source, av[0], av[1], desc, upnumeric); + do_server(source, av[0], atoi(av[1]), desc, upnumeric); delete [] vl; delete [] desc; delete [] upnumeric; } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } ircdproto->SendPing(Config.ServerName, av[0]); @@ -1021,12 +1010,10 @@ int anope_event_error(const char *source, int ac, const char **av) int anope_event_sdesc(const char *source, int ac, const char **av) { - Server *s; - s = findserver(servlist, source); + Server *s = Server::Find(source ? source : ""); - if (s) { - s->desc = const_cast<char *>(av[0]); // XXX Unsafe cast -- CyberBotX - } + if (s) + s->SetDescription(av[0]); return MOD_CONT; } @@ -1188,75 +1175,74 @@ int anope_event_sjoin(const char *source, int ac, const char **av) return MOD_CONT; } -void moduleAddIRCDMsgs() { - Message *m; - - m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m); - m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("6", anope_event_away); addCoreMessage(IRCD,m); - m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("C", anope_event_join); addCoreMessage(IRCD,m); - m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("H", anope_event_kick); addCoreMessage(IRCD,m); - m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage(".", anope_event_kill); addCoreMessage(IRCD,m); - m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("G", anope_event_gmode); addCoreMessage(IRCD,m); - m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("F", anope_event_motd); addCoreMessage(IRCD,m); - m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("&", anope_event_nick); addCoreMessage(IRCD,m); - m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("D", anope_event_part); addCoreMessage(IRCD,m); - m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("8", anope_event_ping); addCoreMessage(IRCD,m); - m = createMessage("PONG", anope_event_pong); addCoreMessage(IRCD,m); - m = createMessage("9", anope_event_pong); addCoreMessage(IRCD,m); - m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("!", anope_event_privmsg); addCoreMessage(IRCD,m); - m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage(",", anope_event_quit); addCoreMessage(IRCD,m); - m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("'", anope_event_server); addCoreMessage(IRCD,m); - m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("-", anope_event_squit); addCoreMessage(IRCD,m); - m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage(")", anope_event_topic); addCoreMessage(IRCD,m); - m = createMessage("SVSMODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("n", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("SVS2MODE", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("v", anope_event_mode); addCoreMessage(IRCD,m); - m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("#", anope_event_whois); addCoreMessage(IRCD,m); - m = createMessage("PROTOCTL", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("_", anope_event_capab); addCoreMessage(IRCD,m); - m = createMessage("CHGHOST", anope_event_chghost); addCoreMessage(IRCD,m); - m = createMessage("AL", anope_event_chghost); addCoreMessage(IRCD,m); - m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m); - m = createMessage("AZ", anope_event_chgident); addCoreMessage(IRCD,m); - m = createMessage("CHGNAME", anope_event_chgname); addCoreMessage(IRCD,m); - m = createMessage("BK", anope_event_chgname); addCoreMessage(IRCD,m); - m = createMessage("NETINFO", anope_event_netinfo); addCoreMessage(IRCD,m); - m = createMessage("AO", anope_event_netinfo); addCoreMessage(IRCD,m); - m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m); - m = createMessage("AA", anope_event_sethost); addCoreMessage(IRCD,m); - m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m); - m = createMessage("AD", anope_event_setident); addCoreMessage(IRCD,m); - m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m); - m = createMessage("AE", anope_event_setname); addCoreMessage(IRCD,m); - m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m); - m = createMessage("5", anope_event_error); addCoreMessage(IRCD,m); - m = createMessage("UMODE2", anope_event_umode2); addCoreMessage(IRCD,m); - m = createMessage("|", anope_event_umode2); addCoreMessage(IRCD,m); - m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m); - m = createMessage("~", anope_event_sjoin); addCoreMessage(IRCD,m); - m = createMessage("SDESC", anope_event_sdesc); addCoreMessage(IRCD,m); - m = createMessage("AG", anope_event_sdesc); addCoreMessage(IRCD,m); +void moduleAddIRCDMsgs() +{ + Anope::AddMessage("436", anope_event_436); + Anope::AddMessage("AWAY", anope_event_away); + Anope::AddMessage("6", anope_event_away); + Anope::AddMessage("JOIN", anope_event_join); + Anope::AddMessage("C", anope_event_join); + Anope::AddMessage("KICK", anope_event_kick); + Anope::AddMessage("H", anope_event_kick); + Anope::AddMessage("KILL", anope_event_kill); + Anope::AddMessage(".", anope_event_kill); + Anope::AddMessage("MODE", anope_event_mode); + Anope::AddMessage("G", anope_event_gmode); + Anope::AddMessage("MOTD", anope_event_motd); + Anope::AddMessage("F", anope_event_motd); + Anope::AddMessage("NICK", anope_event_nick); + Anope::AddMessage("&", anope_event_nick); + Anope::AddMessage("PART", anope_event_part); + Anope::AddMessage("D", anope_event_part); + Anope::AddMessage("PING", anope_event_ping); + Anope::AddMessage("8", anope_event_ping); + Anope::AddMessage("PONG", anope_event_pong); + Anope::AddMessage("9", anope_event_pong); + Anope::AddMessage("PRIVMSG", anope_event_privmsg); + Anope::AddMessage("!", anope_event_privmsg); + Anope::AddMessage("QUIT", anope_event_quit); + Anope::AddMessage(",", anope_event_quit); + Anope::AddMessage("SERVER", anope_event_server); + Anope::AddMessage("'", anope_event_server); + Anope::AddMessage("SQUIT", anope_event_squit); + Anope::AddMessage("-", anope_event_squit); + Anope::AddMessage("TOPIC", anope_event_topic); + Anope::AddMessage(")", anope_event_topic); + Anope::AddMessage("SVSMODE", anope_event_mode); + Anope::AddMessage("n", anope_event_mode); + Anope::AddMessage("SVS2MODE", anope_event_mode); + Anope::AddMessage("v", anope_event_mode); + Anope::AddMessage("WHOIS", anope_event_whois); + Anope::AddMessage("#", anope_event_whois); + Anope::AddMessage("PROTOCTL", anope_event_capab); + Anope::AddMessage("_", anope_event_capab); + Anope::AddMessage("CHGHOST", anope_event_chghost); + Anope::AddMessage("AL", anope_event_chghost); + Anope::AddMessage("CHGIDENT", anope_event_chgident); + Anope::AddMessage("AZ", anope_event_chgident); + Anope::AddMessage("CHGNAME", anope_event_chgname); + Anope::AddMessage("BK", anope_event_chgname); + Anope::AddMessage("NETINFO", anope_event_netinfo); + Anope::AddMessage("AO", anope_event_netinfo); + Anope::AddMessage("SETHOST", anope_event_sethost); + Anope::AddMessage("AA", anope_event_sethost); + Anope::AddMessage("SETIDENT", anope_event_setident); + Anope::AddMessage("AD", anope_event_setident); + Anope::AddMessage("SETNAME", anope_event_setname); + Anope::AddMessage("AE", anope_event_setname); + Anope::AddMessage("ERROR", anope_event_error); + Anope::AddMessage("5", anope_event_error); + Anope::AddMessage("UMODE2", anope_event_umode2); + Anope::AddMessage("|", anope_event_umode2); + Anope::AddMessage("SJOIN", anope_event_sjoin); + Anope::AddMessage("~", anope_event_sjoin); + Anope::AddMessage("SDESC", anope_event_sdesc); + Anope::AddMessage("AG", anope_event_sdesc); /* The non token version of these is in messages.c */ - m = createMessage("2", m_stats); addCoreMessage(IRCD,m); - m = createMessage(">", m_time); addCoreMessage(IRCD,m); - m = createMessage("+", m_version); addCoreMessage(IRCD,m); + Anope::AddMessage("2", m_stats); + Anope::AddMessage(">", m_time); + Anope::AddMessage("+", m_version); } /* Borrowed part of this check from UnrealIRCd */ @@ -1292,39 +1278,39 @@ bool ChannelModeFlood::IsValid(const std::string &value2) static void AddModes() { - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', '%')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@')); /* Unreal sends +q as * and +a as ~ */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '~')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '*')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', '~')); + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '*')); /* Unreal sends +q as * */ /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A')); - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); - ModeManager::AddUserMode(new UserMode(UMODE_CO_ADMIN, 'C')); - ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G')); - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); - ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, 'N')); - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'S')); - ModeManager::AddUserMode(new UserMode(UMODE_NO_CTCP, 'T')); - ModeManager::AddUserMode(new UserMode(UMODE_WEBTV, 'V')); - ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W')); - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); - ModeManager::AddUserMode(new UserMode(UMODE_GLOBOPS, 'g')); - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'p')); - ModeManager::AddUserMode(new UserMode(UMODE_GOD, 'q')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_VHOST, 't')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); - ModeManager::AddUserMode(new UserMode(UMODE_SSL, 'z')); + ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, "UMODE_SERV_ADMIN", 'A')); + ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B')); + ModeManager::AddUserMode(new UserMode(UMODE_CO_ADMIN, "UMODE_CO_ADMIN", 'C')); + ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G')); + ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H')); + ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, "UMODE_NETADMIN", 'N')); + ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R')); + ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'S')); + ModeManager::AddUserMode(new UserMode(UMODE_NO_CTCP, "UMODE_NO_CTCP", 'T')); + ModeManager::AddUserMode(new UserMode(UMODE_WEBTV, "UMODE_WEBTV", 'V')); + ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W')); + ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd')); + ModeManager::AddUserMode(new UserMode(UMODE_GLOBOPS, "UMODE_GLOBOPS", 'g')); + ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h')); + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i')); + ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o')); + ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'p')); + ModeManager::AddUserMode(new UserMode(UMODE_GOD, "UMODE_GOD", 'q')); + ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode(UMODE_VHOST, "UMODE_VHOST", 't')); + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x')); + ModeManager::AddUserMode(new UserMode(UMODE_SSL, "UMODE_SSL", 'z')); } class ProtoUnreal : public Module diff --git a/src/regchannel.cpp b/src/regchannel.cpp index 8eb4b28f0..8ee823e33 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -23,7 +23,6 @@ ChannelInfo::ChannelInfo(const std::string &chname) if (chname.empty()) throw CoreException("Empty channel passed to ChannelInfo constructor"); - next = prev = NULL; founder = successor = NULL; desc = url = email = last_topic = forbidby = forbidreason = NULL; last_topic_time = 0; @@ -61,7 +60,8 @@ ChannelInfo::ChannelInfo(const std::string &chname) this->ttb[i] = 0; reset_levels(this); - alpha_insert_chan(this); + + RegisteredChannelList[this->name.c_str()] = this; } /** Default destructor, cleans up the channel complete and removes it from the internal list @@ -84,12 +84,8 @@ ChannelInfo::~ChannelInfo() this->c->ci = NULL; } - if (this->next) - this->next->prev = this->prev; - if (this->prev) - this->prev->next = this->next; - else - chanlists[static_cast<unsigned char>(tolower(this->name[1]))] = this->next; + RegisteredChannelList.erase(this->name.c_str()); + if (this->desc) delete [] this->desc; if (this->url) @@ -142,7 +138,6 @@ ChannelInfo::~ChannelInfo() void ChannelInfo::AddAccess(NickCore *nc, int16 level, const std::string &creator, int32 last_seen) { ChanAccess *new_access = new ChanAccess(); - new_access->in_use = 1; new_access->nc = nc; new_access->level = level; new_access->last_seen = last_seen; @@ -185,7 +180,7 @@ ChanAccess *ChannelInfo::GetAccess(NickCore *nc, int16 level) return NULL; for (unsigned i = 0; i < access.size(); i++) - if (access[i]->in_use && access[i]->nc == nc && (level ? access[i]->level == level : true)) + if (access[i]->nc == nc && (level ? access[i]->level == level : true)) return access[i]; return NULL; @@ -214,25 +209,16 @@ void ChannelInfo::EraseAccess(unsigned index) access.erase(access.begin() + index); } -/** Cleans the channel access list - * - * Cleans up the access list so it no longer contains entries no longer in use. - */ -void ChannelInfo::CleanAccess() -{ - for (unsigned j = access.size(); j > 0; --j) - if (!access[j - 1]->in_use) - EraseAccess(j - 1); -} - /** Clear the entire channel access list * * Clears the entire access list by deleting every item and then clearing the vector. */ void ChannelInfo::ClearAccess() { - while (access.begin() != access.end()) + while (!access.empty()) + { EraseAccess(0); + } } /** Add an akick entry to the channel by NickCore @@ -249,7 +235,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons return NULL; AutoKick *autokick = new AutoKick(); - autokick->InUse = true; autokick->SetFlag(AK_ISNICK); autokick->nc = akicknc; autokick->reason = reason; @@ -259,8 +244,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons akick.push_back(autokick); - FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(this, autokick)); - return autokick; } @@ -276,7 +259,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask { AutoKick *autokick = new AutoKick(); autokick->mask = mask; - autokick->InUse = true; autokick->reason = reason; autokick->creator = user; autokick->addtime = t; @@ -284,8 +266,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask akick.push_back(autokick); - FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(this, autokick)); - return autokick; } @@ -310,40 +290,27 @@ const unsigned ChannelInfo::GetAkickCount() const } /** Erase an entry from the channel akick list - * @param akick The akick + * @param index The index of the akick */ -void ChannelInfo::EraseAkick(AutoKick *autokick) +void ChannelInfo::EraseAkick(unsigned index) { - std::vector<AutoKick *>::iterator it = std::find(akick.begin(), akick.end(), autokick); - - if (it != akick.end()) - { - FOREACH_MOD(I_OnAkickDel, OnAkickDel(this, *it)); - - delete *it; - akick.erase(it); - } + if (akick.empty() || index > akick.size()) + return; + + delete akick[index]; + akick.erase(akick.begin() + index); } /** Clear the whole akick list */ void ChannelInfo::ClearAkick() { - for (unsigned i = akick.size(); i > 0; --i) + while (!akick.empty()) { - EraseAkick(akick[i - 1]); + EraseAkick(0); } } -/** Clean all of the nonused entries from the akick list - */ -void ChannelInfo::CleanAkick() -{ - for (unsigned i = akick.size(); i > 0; --i) - if (!akick[i - 1]->InUse) - EraseAkick(akick[i - 1]); -} - /** Add a badword to the badword list * @param word The badword * @param type The type (SINGLE START END) @@ -352,7 +319,6 @@ void ChannelInfo::CleanAkick() BadWord *ChannelInfo::AddBadWord(const std::string &word, BadWordType type) { BadWord *bw = new BadWord; - bw->InUse = true; bw->word = word; bw->type = type; @@ -384,37 +350,98 @@ const unsigned ChannelInfo::GetBadWordCount() const } /** Remove a badword - * @param badword The badword + * @param index The index of the badword */ -void ChannelInfo::EraseBadWord(BadWord *badword) +void ChannelInfo::EraseBadWord(unsigned index) { - std::vector<BadWord *>::iterator it = std::find(badwords.begin(), badwords.end(), badword); - - if (it != badwords.end()) - { - FOREACH_MOD(I_OnBadWordDel, OnBadWordDel(this, *it)); - delete *it; - badwords.erase(it); - } + if (badwords.empty() || index >= badwords.size()) + return; + + delete badwords[index]; + badwords.erase(badwords.begin() + index); } /** Clear all badwords from the channel */ void ChannelInfo::ClearBadWords() { - for (unsigned i = badwords.size(); i > 0; --i) + while (!badwords.empty()) { - EraseBadWord(badwords[i - 1]); + EraseBadWord(0); } } -/** Clean all of the nonused entries from the badwords list +/** Loads MLocked modes from extensible. This is used from database loading because Anope doesn't know what modes exist + * until after it connects to the IRCd. */ -void ChannelInfo::CleanBadWords() +void ChannelInfo::LoadMLock() { - for (unsigned i = badwords.size(); i > 0; --i) - if (!badwords[i - 1]->InUse) - EraseBadWord(badwords[i - 1]); + std::vector<std::string> modenames; + + if (this->GetExtRegular("db_mlock_modes_on", modenames)) + { + for (std::vector<std::string>::iterator it = modenames.begin(); it != modenames.end(); ++it) + { + for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit) + { + if ((*mit)->Class == MC_CHANNEL) + { + ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit); + + if (cm->NameAsString == *it) + { + this->SetMLock(cm->Name, true); + } + } + } + } + + this->Shrink("db_mlock_modes_on"); + } + + if (this->GetExtRegular("db_mlock_modes_off", modenames)) + { + for (std::vector<std::string>::iterator it = modenames.begin(); it != modenames.end(); ++it) + { + for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit) + { + if ((*mit)->Class == MC_CHANNEL) + { + ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit); + + if (cm->NameAsString == *it) + { + this->SetMLock(cm->Name, false); + } + } + } + } + + this->Shrink("db_mlock_modes_off"); + } + + std::vector<std::pair<std::string, std::string> > params; + + if (this->GetExtRegular("db_mlp", params)) + { + for (std::vector<std::pair<std::string, std::string> >::iterator it = params.begin(); it != params.end(); ++it) + { + for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit) + { + if ((*mit)->Class == MC_CHANNEL) + { + ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit); + + if (cm->NameAsString == it->first) + { + this->SetMLock(cm->Name, true, it->second); + } + } + } + } + + this->Shrink("db_mlp"); + } } /** Check if a mode is mlocked @@ -425,9 +452,9 @@ void ChannelInfo::CleanBadWords() const bool ChannelInfo::HasMLock(ChannelModeName Name, bool status) { if (status) - return mlock_on[Name]; + return mlock_on.HasFlag(Name); else - return mlock_off[Name]; + return mlock_off.HasFlag(Name); } /** Set a mlock @@ -438,8 +465,6 @@ const bool ChannelInfo::HasMLock(ChannelModeName Name, bool status) */ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string param) { - size_t value = Name; - if (!status && !param.empty()) throw CoreException("Was told to mlock a mode negatively with a param?"); @@ -449,8 +474,8 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string return false; /* First, remove this everywhere */ - mlock_on[value] = false; - mlock_off[value] = false; + mlock_on.UnsetFlag(Name); + mlock_off.UnsetFlag(Name); std::map<ChannelModeName, std::string>::iterator it = Params.find(Name); if (it != Params.end()) @@ -459,9 +484,9 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string } if (status) - mlock_on[value] = true; + mlock_on.SetFlag(Name); else - mlock_off[value] = true; + mlock_off.SetFlag(Name); if (status && !param.empty()) { @@ -477,15 +502,13 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string */ bool ChannelInfo::RemoveMLock(ChannelModeName Name) { - size_t value = Name; - EventReturn MOD_RESULT; FOREACH_RESULT(I_OnUnMLock, OnUnMLock(Name)); if (MOD_RESULT == EVENT_STOP) return false; - mlock_on[value] = false; - mlock_off[value] = false; + mlock_on.UnsetFlag(Name); + mlock_off.UnsetFlag(Name); std::map<ChannelModeName, std::string>::iterator it = Params.find(Name); if (it != Params.end()) @@ -500,8 +523,8 @@ bool ChannelInfo::RemoveMLock(ChannelModeName Name) */ void ChannelInfo::ClearMLock() { - mlock_on.reset(); - mlock_off.reset(); + mlock_on.ClearFlags(); + mlock_off.ClearFlags(); } /** Get the number of mlocked modes for this channel @@ -511,9 +534,9 @@ void ChannelInfo::ClearMLock() const size_t ChannelInfo::GetMLockCount(bool status) const { if (status) - return mlock_on.count(); + return mlock_on.FlagCount(); else - return mlock_off.count(); + return mlock_off.FlagCount(); } /** Get a param from the channel @@ -564,7 +587,7 @@ void ChannelInfo::ClearParams() */ bool ChannelInfo::CheckKick(User *user) { - AutoKick *akick; + AutoKick *autokick; bool set_modes = false, do_kick = false; NickCore *nc; char mask[BUFSIZE]; @@ -573,13 +596,19 @@ bool ChannelInfo::CheckKick(User *user) if (!user || !this->c) return false; - if (user->isSuperAdmin == 1) + if (user->isSuperAdmin) return false; /* We don't enforce services restrictions on clients on ulined services * as this will likely lead to kick/rejoin floods. ~ Viper */ - if (is_ulined(user->server->name)) + if (user->server->IsULined()) + return false; + + if (!do_kick && user->IsProtected()) return false; + + if (ircd->chansqline && SQLineManager::Check(this->c)) + do_kick = true; if (!is_oper(user) && (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN))) { @@ -589,34 +618,34 @@ bool ChannelInfo::CheckKick(User *user) do_kick = true; } + if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1) + return false; + if (user->Account() || user->IsRecognized()) nc = user->Account(); else nc = NULL; - if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1) - return false; - - for (unsigned j = 0; j < this->GetAkickCount(); ++j) + if (!do_kick) { - akick = this->GetAkick(j); - - if (!akick->InUse || do_kick) - continue; - - if ((akick->HasFlag(AK_ISNICK) && akick->nc == nc) - || (!akick->HasFlag(AK_ISNICK) - && match_usermask(akick->mask.c_str(), user))) + for (unsigned j = 0; j < this->GetAkickCount(); ++j) { - Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (akick->HasFlag(AK_ISNICK) ? -akick->nc->display : akick->mask); - akick->last_used = time(NULL); - if (akick->HasFlag(AK_ISNICK)) - get_idealban(this, user, mask, sizeof(mask)); - else - strlcpy(mask, akick->mask.c_str(), sizeof(mask)); - reason = !akick->reason.empty() ? akick->reason.c_str() : Config.CSAutokickReason; - do_kick = true; + autokick = this->GetAkick(j); + + if ((autokick->HasFlag(AK_ISNICK) && autokick->nc == nc) + || (!autokick->HasFlag(AK_ISNICK) + && match_usermask(autokick->mask.c_str(), user))) + { + Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (autokick->HasFlag(AK_ISNICK) ? autokick->nc->display : autokick->mask); + autokick->last_used = time(NULL); + if (autokick->HasFlag(AK_ISNICK)) + get_idealban(this, user, mask, sizeof(mask)); + else + strlcpy(mask, autokick->mask.c_str(), sizeof(mask)); + reason = !autokick->reason.empty() ? autokick->reason.c_str() : Config.CSAutokickReason; + do_kick = true; + break; + } } } @@ -631,7 +660,7 @@ akick->nc->display : akick->mask); if (!do_kick) return false; - Alog(LOG_DEBUG) << "channel: Autokicking "<< user->GetMask() << " from " << this->name; + Alog(LOG_DEBUG) << "Autokicking "<< user->GetMask() << " from " << this->name; /* If the channel isn't syncing and doesn't have any users, join ChanServ * NOTE: we use usercount == 1 here as there is one user, but they are about to be destroyed @@ -648,7 +677,7 @@ akick->nc->display : akick->mask); } /* Join ChanServ */ - ircdproto->SendJoin(findbot(Config.s_ChanServ), this->name.c_str(), this->c->creation_time); + ircdproto->SendJoin(ChanServ, this->name.c_str(), this->c->creation_time); /* Set a timer for this channel to part ChanServ later */ new ChanServTimer(this->c); diff --git a/src/send.c b/src/send.cpp index e16856598..4209e2a1b 100644 --- a/src/send.c +++ b/src/send.cpp @@ -32,6 +32,15 @@ void send_cmd(const char *source, const char *fmt, ...) vsnprintf(buf, BUFSIZE - 1, fmt, args); + if (!UplinkSock) + { + if (source) + Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL"; + else + Alog(LOG_DEBUG) << "Attemtped to send \"" << buf << "\" with UplinkSock NULL"; + return; + } + if (source) { UplinkSock->Write(":%s %s", source, buf); @@ -59,6 +68,15 @@ void send_cmd(const std::string &source, const char *fmt, ...) vsnprintf(buf, BUFSIZE - 1, fmt, args); + if (!UplinkSock) + { + if (!source.empty()) + Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL"; + else + Alog(LOG_DEBUG) << "Attemtped to send " << buf << "\" with UplinkSock NULL"; + return; + } + if (!source.empty()) { UplinkSock->Write(":%s %s", source.c_str(), buf); diff --git a/src/servers.c b/src/servers.c deleted file mode 100644 index 0978e8f30..000000000 --- a/src/servers.c +++ /dev/null @@ -1,702 +0,0 @@ -/* Routines to maintain a list of connected servers - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "modules.h" - -Server *servlist = NULL; -Server *me_server = NULL; /* This are we */ -Server *serv_uplink = NULL; /* This is our uplink */ -Flags<CapabType> Capab; -char *uplink; -char *TS6UPLINK; -char *TS6SID; - -/* For first_server / next_server */ -static Server *server_cur; - -CapabInfo Capab_Info[] = { - {"NOQUIT", CAPAB_NOQUIT}, - {"TSMODE", CAPAB_TSMODE}, - {"UNCONNECT", CAPAB_UNCONNECT}, - {"NICKIP", CAPAB_NICKIP}, - {"SSJOIN", CAPAB_NSJOIN}, - {"ZIP", CAPAB_ZIP}, - {"BURST", CAPAB_BURST}, - {"TS5", CAPAB_TS5}, - {"TS3", CAPAB_TS3}, - {"DKEY", CAPAB_DKEY}, - {"PT4", CAPAB_PT4}, - {"SCS", CAPAB_SCS}, - {"QS", CAPAB_QS}, - {"UID", CAPAB_UID}, - {"KNOCK", CAPAB_KNOCK}, - {"CLIENT", CAPAB_CLIENT}, - {"IPV6", CAPAB_IPV6}, - {"SSJ5", CAPAB_SSJ5}, - {"SN2", CAPAB_SN2}, - {"TOK1", CAPAB_TOKEN}, - {"TOKEN", CAPAB_TOKEN}, - {"VHOST", CAPAB_VHOST}, - {"SSJ3", CAPAB_SSJ3}, - {"SJB64", CAPAB_SJB64}, - {"CHANMODES", CAPAB_CHANMODE}, - {"NICKCHARS", CAPAB_NICKCHARS}, - {"", CAPAB_END} -}; - -/*************************************************************************/ - -/** - * Return the first server in the server struct - * @param flag Server Flag, see services.h - * @return Server Struct - */ -Server *first_server(ServerFlag flag) -{ - server_cur = servlist; - - while (server_cur && !server_cur->HasFlag(flag)) - server_cur = next_server(flag); - return server_cur; -} - -/*************************************************************************/ - -/** - * Return the next server in the server struct - * @param flags Server Flags, see services.h - * @return Server Struct - */ -Server *next_server(ServerFlag flag) -{ - if (!server_cur) - return NULL; - - do { - if (server_cur->links) { - server_cur = server_cur->links; - } else if (server_cur->next) { - server_cur = server_cur->next; - } else { - do { - server_cur = server_cur->uplink; - if (server_cur && server_cur->next) { - server_cur = server_cur->next; - break; - } - } while (server_cur); - } - } while (server_cur && !server_cur->HasFlag(flag)); - - return server_cur; -} - -/*************************************************************************/ - -/** - * This function makes a new Server structure and links it in the right - * places in the linked list if a Server struct to it's uplink if provided. - * It can also be NULL to indicate it's the uplink and should be first in - * the server list. - * @param server_uplink Server struct - * @param name Server Name - * @param desc Server Description - * @param flags Server Flags, see services.h - * @param suid Server Universal ID - * @return Server Struct - */ -Server *new_server(Server * server_uplink, const char *name, const char *desc, - ServerFlag flag, const std::string &suid) -{ - Server *serv; - - Alog(LOG_DEBUG) << "Creating " << name << "(" << suid << ") uplinked to " << (server_uplink ? server_uplink->name : "No uplink"); - serv = new Server; - if (!name) - name = ""; - serv->name = sstrdup(name); - serv->desc = sstrdup(desc); - if (flag != SERVER_START) - serv->SetFlag(flag); - serv->uplink = server_uplink; - if (!suid.empty()) - serv->suid = sstrdup(suid.c_str()); - else - serv->suid = NULL; - - serv->sync = SSYNC_IN_PROGRESS; - serv->links = NULL; - serv->prev = NULL; - - if (!server_uplink) { - serv->hops = 0; - serv->next = servlist; - if (servlist) - servlist->prev = serv; - servlist = serv; - } else { - serv->hops = server_uplink->hops + 1; - serv->next = server_uplink->links; - if (server_uplink->links) - server_uplink->links->prev = serv; - server_uplink->links = serv; - } - - /* Check if this is our uplink server */ - if ((server_uplink == me_server) && flag != SERVER_JUPED) - { - // XXX: Apparantly we set ourselves as serv_uplink before we (really) set the uplink when we recieve SERVER. This is wrong and ugly. - if (serv_uplink != NULL) - { - /* Bring in our pseudo-clients */ - introduce_user(""); - - /* And hybrid needs Global joined in the logchan */ - if (LogChan && ircd->join2msg) { - /* XXX might desync */ - ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, time(NULL)); - } - } - serv_uplink = serv; - serv->SetFlag(SERVER_ISUPLINK); - } - - return serv; -} - -/*************************************************************************/ - -/** - * Remove and free a Server structure. This function is the most complete - * remove treatment a server can get, as it first quits all clients which - * still pretend to be on this server, then it walks through all connected - * servers and disconnects them too. If all mess is cleared, the server - * itself will be too. - * @param Server struct - * @param reason the server quit - * @return void - */ -static void delete_server(Server * serv, const char *quitreason) -{ - Server *s, *snext; - User *u, *unext; - NickAlias *na; - - if (!serv) { - Alog(LOG_DEBUG) << "delete_server() called with NULL arg!"; - return; - } - - Alog(LOG_DEBUG) << "delete_server() called, deleting " << serv->name << "(" << serv->suid << ") uplinked to " - << (serv->uplink ? serv->uplink->name : "NOTHING") << "(" - << (serv->uplink ? serv->uplink->suid : "NOSUIDUPLINK") << ")"; - - if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS)) - { - u = firstuser(); - while (u) - { - unext = nextuser(); - if (u->server == serv) - { - if ((na = findnick(u->nick)) && !na->HasFlag(NS_FORBIDDEN) - && (!na->nc->HasFlag(NI_SUSPENDED)) - && (u->IsRecognized() || u->IsIdentified())) { - na->last_seen = time(NULL); - if (na->last_quit) - delete [] na->last_quit; - na->last_quit = (quitreason ? sstrdup(quitreason) : NULL); - } - if (Config.LimitSessions && !is_ulined(u->server->name)) { - del_session(u->host); - } - delete u; - } - u = unext; - } - Alog(LOG_DEBUG) << "delete_server() cleared all users"; - } - - s = serv->links; - while (s) { - snext = s->next; - delete_server(s, quitreason); - s = snext; - } - - Alog(LOG_DEBUG) << "delete_server() cleared all servers"; - - delete [] serv->name; - delete [] serv->desc; - if (serv->prev) - serv->prev->next = serv->next; - if (serv->next) - serv->next->prev = serv->prev; - if (serv->uplink->links == serv) - serv->uplink->links = serv->next; - - Alog(LOG_DEBUG) << "delete_server() completed"; -} - -/*************************************************************************/ - -/** - * Find a server by name, returns NULL if not found - * @param s Server struct - * @param name Server Name - * @return Server struct - */ -Server *findserver(Server * s, const char *name) -{ - Server *sl; - - if (!name || !*name) { - return NULL; - } - - Alog(LOG_DEBUG) << "findserver(" << name << ")"; - - while (s && (stricmp(s->name, name) != 0)) - { - Alog(LOG_DEBUG_3) << "Compared " << s->name << ", not a match"; - if (s->links) - { - sl = findserver(s->links, name); - if (sl) - { - s = sl; - } - else - { - s = s->next; - } - } - else - { - s = s->next; - } - } - - Alog(LOG_DEBUG) << "findserver(" << name << ") -> " << static_cast<void *>(s); - return s; -} - -/*************************************************************************/ - -/** - * Find a server by UID, returns NULL if not found - * @param s Server struct - * @param name Server Name - * @return Server struct - */ -Server *findserver_uid(Server * s, const char *name) -{ - Server *sl; - - if (!name || !*name) { - return NULL; - } - - Alog(LOG_DEBUG) << "findserver_uid(" << name << ")"; - - while (s && s->suid && (stricmp(s->suid, name) != 0)) - { - Alog(LOG_DEBUG_3) << "Compared " << s->suid << ", not a match"; - if (s->links) - { - sl = findserver_uid(s->links, name); - if (sl) - { - s = sl; - } - else - { - s = s->next; - } - } - else - { - s = s->next; - } - } - - Alog(LOG_DEBUG) << "findserver_uid(" << name << ") -> " << static_cast<void *>(s); - return s; -} - -/*************************************************************************/ - -/** - * Find if the server is synced with the network - * @param s Server struct - * @param name Server Name - * @return Not Synced returns -1, Synced returns 1, Error returns 0 - */ -int anope_check_sync(const char *name) -{ - Server *s; - s = findserver(servlist, name); - - if (!s) - return 0; - - if (is_sync(s)) - return 1; - else - return -1; -} - -/*************************************************************************/ - -/** - * Handle adding the server to the Server struct - * @param source Name of the uplink if any - * @param servername Name of the server being linked - * @param hops Number of hops to reach this server - * @param descript Description of the server - * @param numeric Server Numberic/SUID - * @return void - */ -void do_server(const char *source, const char *servername, const char *hops, - const char *descript, const std::string &numeric) -{ - Server *s, *newserver; - - Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << (*source ? " from " : "") << (*source ? source : ""); - - - if (source[0] == '\0') - s = me_server; - else - s = findserver(servlist, source); - - if (s == NULL) - s = findserver_uid(servlist, source); - - if (s == NULL) - throw CoreException("Recieved a server from a nonexistant uplink?"); - - /* Create a server structure. */ - newserver = new_server(s, servername, descript, SERVER_START, numeric); - - /* Announce services being online. */ - if (Config.GlobalOnCycle && Config.GlobalOnCycleUP) - notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP); - - /* Let modules know about the connection */ - FOREACH_MOD(I_OnNewServer, OnNewServer(newserver)); -} - -/*************************************************************************/ - -/** - * Handle removing the server from the Server struct - * @param source Name of the server leaving - * @param ac Number of arguments in av - * @param av Agruments as part of the SQUIT - * @return void - */ -void do_squit(const char *source, int ac, const char **av) -{ - char buf[BUFSIZE]; - Server *s; - - if (ircd->ts6) { - s = findserver_uid(servlist, av[0]); - if (!s) { - s = findserver(servlist, av[0]); - } - } else { - s = findserver(servlist, av[0]); - } - if (!s) - { - Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!"; - return; - } - FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); - - /* If this is a juped server, send a nice global to inform the online - * opers that we received it. - */ - if (s->HasFlag(SERVER_JUPED)) - { - snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s", - s->name); - ircdproto->SendGlobops(findbot(Config.s_OperServ), buf); - } - - snprintf(buf, sizeof(buf), "%s %s", s->name, - (s->uplink ? s->uplink->name : "")); - - if (s->uplink == me_server && Capab.HasFlag(CAPAB_UNCONNECT)) - { - Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->name; - /* need to fix */ - ircdproto->SendSquit(s->name, buf); - } - - delete_server(s, buf); -} - -/*************************************************************************/ - -/** Handle parsing the CAPAB/PROTOCTL messages - * @param ac Number of args - * @param av Args - */ -void CapabParse(int ac, const char **av) -{ - for (int i = 0; i < ac; ++i) - { - for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j) - { - if (av[i] == Capab_Info[j].Token) - { - Capab.SetFlag(Capab_Info[j].Flag); - - if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip) - ircd->nickip = 1; - break; - } - } - } -} - -/*************************************************************************/ - -/** - * Search the uline servers array to find out if the server that just set the - * mode is in our uline list - * @param server Server Setting the mode - * @return int 0 if not found, 1 if found - */ -int is_ulined(const char *server) -{ - int j; - - for (j = 0; j < Config.NumUlines; j++) { - if (stricmp(Config.Ulines[j], server) == 0) { - return 1; - } - } - - return 0; -} - -/*************************************************************************/ - -/** - * See if the current server is synced, or has an unknown sync state - * (in which case we pretend it is always synced) - * @param server Server of which we want to know the state - * @return int 0 if not synced, 1 if synced - */ -int is_sync(Server * server) -{ - if (server->sync == SSYNC_DONE) - return 1; - return 0; -} - -/*************************************************************************/ - -/* Finish the syncing process for this server and (optionally) for all - * it's leaves as well - * @param serv Server to finish syncing - * @param sync_links Should all leaves be synced as well? (1: yes, 0: no) - * @return void - */ -void finish_sync(Server * serv, int sync_links) -{ - Server *s; - - if (!serv || is_sync(serv)) - return; - - /* Mark each server as in sync */ - s = serv; - do { - if (!is_sync(s)) - { - Alog(LOG_DEBUG) << "Finishing sync for server " << s->name; - s->sync = SSYNC_DONE; - } - - if (!sync_links) - break; - - if (s->links) { - s = s->links; - } else if (s->next) { - s = s->next; - } else { - do { - s = s->uplink; - if (s == serv) - s = NULL; - if (s == me_server) - s = NULL; - } while (s && !(s->next)); - if (s) - s = s->next; - } - } while (s); - - if (serv == serv_uplink) - { - FOREACH_MOD(I_OnFinishSync, OnFinishSync(serv)); - ircdproto->SendEOB(); - } - - /* Do some general stuff which should only be done once */ - // XXX: this doesn't actually match the description. finish_sync(), depending on the ircd, can be called multiple times - // Perhaps this should be done if serv == serv_uplink? - restore_unsynced_topics(); - Alog() << "Server " << serv->name << " is done syncing"; - - FOREACH_MOD(I_OnServerSync, OnServerSync(s)); - if (serv == serv_uplink) - { - FOREACH_MOD(I_OnUplinkSync, OnUplinkSync()); - } -} - -/*******************************************************************/ - -/* TS6 UID generator common code. - * - * Derived from atheme-services, uid.c (hg 2954:116d46894b4c). - * -nenolod - */ -static int ts6_uid_initted = 0; -static char ts6_new_uid[10]; /* allow for \0 */ -static unsigned int ts6_uid_index = 9; /* last slot in uid buf */ - -void ts6_uid_init() -{ - snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID); - ts6_uid_initted = 1; -} - -void ts6_uid_increment(unsigned int slot) -{ - if (slot != strlen(TS6SID)) { - if (ts6_new_uid[slot] == 'Z') - ts6_new_uid[slot] = '0'; - else if (ts6_new_uid[slot] == '9') { - ts6_new_uid[slot] = 'A'; - ts6_uid_increment(slot - 1); - } else - ts6_new_uid[slot]++; - } else { - if (ts6_new_uid[slot] == 'Z') - for (slot = 3; slot < 9; slot++) - ts6_new_uid[slot] = 'A'; - else - ts6_new_uid[slot]++; - } -} - -const char *ts6_uid_retrieve() -{ - if (ircd->ts6 == 0) - { - Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd"; - return ""; - } - - if (ts6_uid_initted != 1) - { - throw CoreException("TS6 IRCd and ts6_uid_init() hasn't been called!"); - } - - ts6_uid_increment(ts6_uid_index - 1); - return ts6_new_uid; -} - -/*******************************************************************/ - -/* - * TS6 generator code, provided by DukePyrolator - */ - -static int ts6_sid_initted = 0; -static char ts6_new_sid[4]; - -static void ts6_sid_increment(unsigned pos) -{ - /* - * An SID must be exactly 3 characters long, starts with a digit, - * and the other two characters are A-Z or digits - * The rules for generating an SID go like this... - * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP - */ - if (!pos) - { - /* At pos 0, if we hit '9', we've run out of available SIDs, - * reset the SID to the smallest possible value and try again. */ - if (ts6_new_sid[pos] == '9') - { - ts6_new_sid[0] = '0'; - ts6_new_sid[1] = 'A'; - ts6_new_sid[2] = 'A'; - } - else - // But if we haven't, just keep incrementing merrily. - ++ts6_new_sid[0]; - } - else - { - if (ts6_new_sid[pos] == 'Z') - ts6_new_sid[pos] = '0'; - else if (ts6_new_sid[pos] == '9') - { - ts6_new_sid[pos] = 'A'; - ts6_sid_increment(pos - 1); - } - else - ++ts6_new_sid[pos]; - } -} - -const char *ts6_sid_retrieve() -{ - if (!ircd->ts6) - { - Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd"; - return ""; - } - - if (!ts6_sid_initted) - { - // Initialize ts6_new_sid with the services server SID - snprintf(ts6_new_sid, 4, "%s", TS6SID); - ts6_sid_initted = 1; - } - while (1) - { - // Check if the new SID is used by a known server - if (!findserver_uid(servlist, ts6_new_sid)) - // return the new SID - return ts6_new_sid; - - // Add one to the last SID - ts6_sid_increment(2); - } - /* not reached */ - return ""; -} - -/* EOF */ diff --git a/src/servers.cpp b/src/servers.cpp new file mode 100644 index 000000000..88b326f47 --- /dev/null +++ b/src/servers.cpp @@ -0,0 +1,585 @@ +/* Routines to maintain a list of connected servers + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ + +#include "services.h" +#include "modules.h" + +char *TS6SID = NULL; + +/* Anope */ +Server *Me = NULL; + +CapabInfo Capab_Info[] = { + {"NOQUIT", CAPAB_NOQUIT}, + {"TSMODE", CAPAB_TSMODE}, + {"UNCONNECT", CAPAB_UNCONNECT}, + {"NICKIP", CAPAB_NICKIP}, + {"SSJOIN", CAPAB_NSJOIN}, + {"ZIP", CAPAB_ZIP}, + {"BURST", CAPAB_BURST}, + {"TS5", CAPAB_TS5}, + {"TS3", CAPAB_TS3}, + {"DKEY", CAPAB_DKEY}, + {"PT4", CAPAB_PT4}, + {"SCS", CAPAB_SCS}, + {"QS", CAPAB_QS}, + {"UID", CAPAB_UID}, + {"KNOCK", CAPAB_KNOCK}, + {"CLIENT", CAPAB_CLIENT}, + {"IPV6", CAPAB_IPV6}, + {"SSJ5", CAPAB_SSJ5}, + {"SN2", CAPAB_SN2}, + {"TOK1", CAPAB_TOKEN}, + {"TOKEN", CAPAB_TOKEN}, + {"VHOST", CAPAB_VHOST}, + {"SSJ3", CAPAB_SSJ3}, + {"SJB64", CAPAB_SJB64}, + {"CHANMODES", CAPAB_CHANMODE}, + {"NICKCHARS", CAPAB_NICKCHARS}, + {"", CAPAB_END} +}; + +Flags<CapabType> Capab; + +/** Constructor + * @param uplink The uplink this server is from, is only NULL when creating Me + * @param name The server name + * @param hops Hops from services server + * @param description Server rdescription + * @param sid Server sid/numeric + */ +Server::Server(Server *uplink, const std::string &name, unsigned int hops, const std::string &description, const std::string &sid) : Name(name), Hops(hops), Description(description), SID(sid), UplinkServer(uplink) +{ + Links = NULL; + + SetFlag(SERVER_SYNCING); + + Alog(LOG_DEBUG) << "Creating " << GetName() << " (" << GetSID() << ") uplinked to " << (UplinkServer ? UplinkServer->GetName() : "no uplink"); + + /* Add this server to our uplinks leaf list */ + if (UplinkServer) + UplinkServer->AddLink(this); + + if (Me && UplinkServer && Me == UplinkServer) + { + /* Bring in our pseudo-clients */ + introduce_user(""); + + /* And some IRCds needs Global joined in the logchan */ + if (LogChan && ircd->join2msg) + { + /* XXX might desync */ + ircdproto->SendJoin(Global, Config.LogChannel, time(NULL)); + } + } +} + +/** Destructor + */ +Server::~Server() +{ + Alog(LOG_DEBUG) << "Deleting server " << GetName() << " (" << GetSID() << ") uplinked to " << GetName(); + + if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS)) + { + time_t t = time(NULL); + + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *u = it->second; + ++it; + + if (u->server == this) + { + NickAlias *na = findnick(u->nick); + if (na && !na->HasFlag(NS_FORBIDDEN) && (!na->nc->HasFlag(NI_SUSPENDED)) && (u->IsRecognized() || u->IsIdentified())) + { + na->last_seen = t; + if (na->last_quit) + delete [] na->last_quit; + na->last_quit = (!QReason.empty() ? sstrdup(QReason.c_str()) : NULL); + } + + if (Config.LimitSessions && !u->server->IsULined()) + { + del_session(u->host); + } + + delete u; + } + } + + Alog(LOG_DEBUG) << "Finished removing all users for " << GetName(); + } + + if (Links) + { + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + delete *it; + } + } + + delete Links; +} + +/** Delete this server with a reason + * @param reason The reason + */ +void Server::Delete(const std::string &reason) +{ + QReason = reason; + delete this; +} + +/** Get the name for this server + * @return The name + */ +const std::string& Server::GetName() const +{ + return Name; +} + +/** Get the number of hops this server is from services + * @return Number of hops + */ +unsigned int Server::GetHops() const +{ + return Hops; +} + +/** Set the server description + * @param desc The new description + */ +void Server::SetDescription(const std::string& desc) +{ + Description = desc; +} + +/** Get the server description + * @return The server description + */ +const std::string& Server::GetDescription() const +{ + return Description; +} + +/** Get the server numeric/SID + * @return The numeric/SID + */ +const std::string& Server::GetSID() const +{ + return SID; +} + +/** Get the list of links this server has, or NULL if it has none + * @return A list of servers + */ +const std::list<Server*>* Server::GetLinks() const +{ + return Links; +} + +/** Get the uplink server for this server, if this is our uplink will be Me + * @return The servers uplink + */ +Server* Server::GetUplink() const +{ + return UplinkServer; +} + +/** Adds a link to this server + * @param s The linking server + */ +void Server::AddLink(Server *s) +{ + /* This is only used for Me, initially we start services with an uplink of NULL, then + * connect to the server which introduces itself and has us as the uplink, which calls this + */ + if (!UplinkServer) + { + UplinkServer = s; + } + else + { + if (!Links) + { + Links = new std::list<Server *>(); + } + + Links->push_back(s); + } + + Alog() << "Server " << s->GetName() << " introduced from " << GetName(); +} + +/** Delinks a server from this server + * @param s The server + */ +void Server::DelLink(Server *s) +{ + if (!Links) + throw CoreException("Server::DelLink called on " + GetName() + " for " + s->GetName() + " but we have no links?"); + + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + if (*it == s) + { + Links->erase(it); + break; + } + } + + if (Links->empty()) + { + delete Links; + Links = NULL; + } + + Alog() << "Server " << s->GetName() << " quit from " << GetName(); +} + +/** Finish syncing this server and optionally all links to it + * @param SyncLinks True to sync the links for this server too (if any) + */ +void Server::Sync(bool SyncLinks) +{ + if (IsSynced()) + return; + + UnsetFlag(SERVER_SYNCING); + + if (SyncLinks && Links) + { + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + (*it)->Sync(true); + } + } + + if (this == Me->GetUplink()) + { + FOREACH_MOD(I_OnPreUplinkSync, OnPreUplinkSync(this)); + ircdproto->SendEOB(); + Me->UnsetFlag(SERVER_SYNCING); + } + + Alog() << "Server " << GetName() << " is done syncing"; + + FOREACH_MOD(I_OnServerSync, OnServerSync(this)); + + if (this == Me->GetUplink()) + { + FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this)); + restore_unsynced_topics(); + } +} + +/** Check if this server is synced + * @return true or false + */ +bool Server::IsSynced() const +{ + return !HasFlag(SERVER_SYNCING); +} + +/** Check if this server is ULined + * @return true or false + */ +bool Server::IsULined() const +{ + for (int j = 0; j < Config.NumUlines; ++j) + if (!stricmp(Config.Ulines[j], GetName().c_str())) + return true; + return false; +} + +/** Find a server + * @param name The name or SID/numeric + * @param s The server list to search for this server on, defaults to our Uplink + * @return The server + */ +Server* Server::Find(const std::string &name, Server *s) +{ + if (!s) + s = Me->GetUplink(); + if (s->GetName() == name || s->GetSID() == name) + return s; + + if (s->GetLinks()) + { + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + Server *serv = *it; + + if (serv->GetName() == name || serv->GetSID() == name) + return serv; + Server *server = Server::Find(name, serv); + if (server) + return server; + } + } + + return NULL; +} + +/*************************************************************************/ + +/** + * Handle adding the server to the Server struct + * @param source Name of the uplink if any + * @param servername Name of the server being linked + * @param hops Number of hops to reach this server + * @param descript Description of the server + * @param numeric Server Numberic/SUID + * @return void + */ +void do_server(const std::string &source, const std::string &servername, unsigned int hops, const std::string &descript, const std::string &numeric) +{ + if (source.empty()) + Alog(LOG_DEBUG) << "Server " << servername << " introduced"; + else + Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << " from " << source; + + Server *s = NULL; + + if (!source.empty()) + { + s = Server::Find(source); + + if (!s) + throw CoreException("Recieved a server from a nonexistant uplink?"); + } + else + s = Me; + + /* Create a server structure. */ + Server *newserver = new Server(s, servername, hops, descript, numeric); + + /* Announce services being online. */ + if (Config.GlobalOnCycle && Config.GlobalOnCycleUP) + notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP); + + /* Let modules know about the connection */ + FOREACH_MOD(I_OnNewServer, OnNewServer(newserver)); +} + +/*************************************************************************/ + +/** + * Handle removing the server from the Server struct + * @param source Name of the server leaving + * @param ac Number of arguments in av + * @param av Agruments as part of the SQUIT + * @return void + */ +void do_squit(const char *source, int ac, const char **av) +{ + char buf[BUFSIZE]; + Server *s = Server::Find(av[0]); + + if (!s) + { + Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!"; + return; + } + + FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); + + /* If this is a juped server, send a nice global to inform the online + * opers that we received it. + */ + if (s->HasFlag(SERVER_JUPED)) + { + snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s", s->GetName().c_str()); + ircdproto->SendGlobops(OperServ, buf); + } + + snprintf(buf, sizeof(buf), "%s %s", s->GetName().c_str(), s->GetUplink()->GetName().c_str()); + + if (s->GetUplink() == Me->GetUplink() && Capab.HasFlag(CAPAB_UNCONNECT)) + { + Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->GetName(); + /* need to fix */ + ircdproto->SendSquit(s->GetName().c_str(), buf); + } + + s->Delete(buf); +} + +/*************************************************************************/ + +/** Handle parsing the CAPAB/PROTOCTL messages + * @param ac Number of args + * @param av Args + */ +void CapabParse(int ac, const char **av) +{ + for (int i = 0; i < ac; ++i) + { + for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j) + { + if (av[i] == Capab_Info[j].Token) + { + Capab.SetFlag(Capab_Info[j].Flag); + + if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip) + ircd->nickip = 1; + break; + } + } + } + + /* Apply MLock now that we know what modes exist (capab is parsed after modes are added to Anope) */ + for (registered_channel_map::iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it) + { + ChannelInfo *ci = it->second; + + ci->LoadMLock(); + } +} + +/*************************************************************************/ + +/* TS6 UID generator common code. + * + * Derived from atheme-services, uid.c (hg 2954:116d46894b4c). + * -nenolod + */ +static bool ts6_uid_initted = false; +static char ts6_new_uid[10]; + +static void ts6_uid_increment(unsigned int slot) +{ + if (slot != strlen(TS6SID)) + { + if (ts6_new_uid[slot] == 'Z') + ts6_new_uid[slot] = '0'; + else if (ts6_new_uid[slot] == '9') + { + ts6_new_uid[slot] = 'A'; + ts6_uid_increment(slot - 1); + } + else + ++ts6_new_uid[slot]; + } + else + { + if (ts6_new_uid[slot] == 'Z') + for (slot = 3; slot < 9; slot++) + ts6_new_uid[slot] = 'A'; + else + ++ts6_new_uid[slot]; + } +} + +/** Recieve the next UID in our list + * @return The UID + */ +const char *ts6_uid_retrieve() +{ + if (ircd->ts6 == 0) + { + Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd"; + return ""; + } + + if (!ts6_uid_initted) + { + snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID); + ts6_uid_initted = true; + } + + ts6_uid_increment(8); + return ts6_new_uid; +} + +/*******************************************************************/ + +/* + * TS6 generator code, provided by DukePyrolator + */ + +static bool ts6_sid_initted = false; +static char ts6_new_sid[4]; + +static void ts6_sid_increment(unsigned pos) +{ + /* + * An SID must be exactly 3 characters long, starts with a digit, + * and the other two characters are A-Z or digits + * The rules for generating an SID go like this... + * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP + */ + if (!pos) + { + /* At pos 0, if we hit '9', we've run out of available SIDs, + * reset the SID to the smallest possible value and try again. */ + if (ts6_new_sid[pos] == '9') + { + ts6_new_sid[0] = '0'; + ts6_new_sid[1] = 'A'; + ts6_new_sid[2] = 'A'; + } + else + // But if we haven't, just keep incrementing merrily. + ++ts6_new_sid[0]; + } + else + { + if (ts6_new_sid[pos] == 'Z') + ts6_new_sid[pos] = '0'; + else if (ts6_new_sid[pos] == '9') + { + ts6_new_sid[pos] = 'A'; + ts6_sid_increment(pos - 1); + } + else + ++ts6_new_sid[pos]; + } +} + +/** Return the next SID in our list + * @return The SID + */ +const char *ts6_sid_retrieve() +{ + if (!ircd->ts6) + { + Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd"; + return ""; + } + + if (!ts6_sid_initted) + { + // Initialize ts6_new_sid with the services server SID + snprintf(ts6_new_sid, 4, "%s", TS6SID); + ts6_sid_initted = true; + } + + while (1) + { + // Check if the new SID is used by a known server + if (!Server::Find(ts6_new_sid)) + // return the new SID + return ts6_new_sid; + + // Add one to the last SID + ts6_sid_increment(2); + } + /* not reached */ + return ""; +} + +/* EOF */ diff --git a/src/sessions.c b/src/sessions.cpp index 0891bec93..e0c20e185 100644 --- a/src/sessions.c +++ b/src/sessions.cpp @@ -12,7 +12,8 @@ */ #include "services.h" -#include "pseudo.h" +#include "modules.h" +#include "language.h" /*************************************************************************/ @@ -50,14 +51,7 @@ /*************************************************************************/ -/* I'm sure there is a better way to hash the list of hosts for which we are - * storing session information. This should be sufficient for the mean time. - * -TheShadow */ - -#define HASH(host) (((host)[0]&31)<<5 | ((host)[1]&31)) - -Session *sessionlist[1024]; -int32 nsessions = 0; +session_map SessionList; Exception *exceptions = NULL; int16 nexceptions = 0; @@ -68,19 +62,17 @@ int16 nexceptions = 0; void get_session_stats(long *nrec, long *memuse) { - Session *session; - long mem; - int i; + long mem = sizeof(Session) * SessionList.size(); - mem = sizeof(Session) * nsessions; - for (i = 0; i < 1024; i++) { - for (session = sessionlist[i]; session; session = session->next) { - mem += strlen(session->host) + 1; - } + for (session_map::const_iterator it = SessionList.begin(); it != SessionList.end(); ++it) + { + Session *session = it->second; + + mem += strlen(session->host) + 1; } - *nrec = nsessions; *memuse = mem; + *nrec = SessionList.size(); } void get_exception_stats(long *nrec, long *memuse) @@ -101,23 +93,12 @@ void get_exception_stats(long *nrec, long *memuse) /********************* Internal Session Functions ************************/ /*************************************************************************/ -Session *findsession(const char *host) +Session *findsession(const std::string &host) { - Session *session; - int i; - - if (!host) { - return NULL; - } - - for (i = 0; i < 1024; i++) { - for (session = sessionlist[i]; session; session = session->next) { - if (stricmp(host, session->host) == 0) { - return session; - } - } - } + session_map::const_iterator it = SessionList.find(host); + if (it != SessionList.end()) + return it->second; return NULL; } @@ -128,7 +109,7 @@ Session *findsession(const char *host) int add_session(const char *nick, const char *host, char *hostip) { - Session *session, **list; + Session *session; Exception *exception; int sessionlimit = 0; @@ -141,9 +122,9 @@ int add_session(const char *nick, const char *host, char *hostip) if (sessionlimit != 0 && session->count >= sessionlimit) { if (Config.SessionLimitExceeded) - ircdproto->SendMessage(findbot(Config.s_OperServ), nick, Config.SessionLimitExceeded, host); + ircdproto->SendMessage(OperServ, nick, Config.SessionLimitExceeded, host); if (Config.SessionLimitDetailsLoc) - ircdproto->SendMessage(findbot(Config.s_OperServ), nick, "%s", Config.SessionLimitDetailsLoc); + ircdproto->SendMessage(OperServ, nick, "%s", Config.SessionLimitDetailsLoc); /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was * decremented in do_quit, which caused problems and fixed here @@ -159,10 +140,10 @@ int add_session(const char *nick, const char *host, char *hostip) if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill) { char akillmask[BUFSIZE]; snprintf(akillmask, sizeof(akillmask), "*@%s", host); - add_akill(NULL, akillmask, Config.s_OperServ, - time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded"); - ircdproto->SendGlobops(findbot(Config.s_OperServ), - "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); + XLine *x = new XLine(ci::string("*@") + host, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded"); + if (x) + x->By = Config.s_OperServ; + ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); } return 0; } else { @@ -171,25 +152,18 @@ int add_session(const char *nick, const char *host, char *hostip) } } - nsessions++; session = new Session; session->host = sstrdup(host); - list = &sessionlist[HASH(session->host)]; - session->prev = NULL; - session->next = *list; - if (*list) - (*list)->prev = session; - *list = session; session->count = 1; session->hits = 0; + SessionList[session->host] = session; + return 1; } void del_session(const char *host) { - Session *session; - if (!Config.LimitSessions) { Alog(LOG_DEBUG) << "del_session called when LimitSessions is disabled"; return; @@ -202,12 +176,12 @@ void del_session(const char *host) Alog(LOG_DEBUG_2) << "del_session() called"; - session = findsession(host); + Session *session = findsession(host); if (!session) { if (debug) { - ircdproto->SendGlobops(findbot(Config.s_OperServ), "WARNING: Tried to delete non-existant session: \2%s", host); + ircdproto->SendGlobops(OperServ, "WARNING: Tried to delete non-existant session: \2%s", host); Alog(LOG_DEBUG) << "session: Tried to delete non-existant session: " << host; } return; @@ -218,20 +192,13 @@ void del_session(const char *host) return; } - if (session->prev) - session->prev->next = session->next; - else - sessionlist[HASH(session->host)] = session->next; - if (session->next) - session->next->prev = session->prev; + SessionList.erase(session->host); Alog(LOG_DEBUG_2) << "del_session(): free session structure"; delete [] session->host; delete session; - nsessions--; - Alog(LOG_DEBUG_2) << "del_session() done"; } @@ -249,7 +216,7 @@ void expire_exceptions() if (exceptions[i].expires == 0 || exceptions[i].expires > now) continue; if (Config.WallExceptionExpire) - ircdproto->SendGlobops(findbot(Config.s_OperServ), + ircdproto->SendGlobops(OperServ, "Session limit exception for %s has expired.", exceptions[i].mask); delete [] exceptions[i].mask; diff --git a/src/slist.c b/src/slist.c deleted file mode 100644 index d01d58ecd..000000000 --- a/src/slist.c +++ /dev/null @@ -1,395 +0,0 @@ -/* Services list handler implementation. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "slist.h" - -static SListOpts slist_defopts = { 0, NULL, NULL, NULL }; - -/*************************************************************************/ - -/** - * Adds a pointer to the list. Returns the index of the new item. - * Returns -2 if there are too many items in the list, -3 if the - * item already exists when the flags of the list contain SLISTF_NODUP. - * @param slist Slist Struct - * @param item Item being added - * @return int - */ -int slist_add(SList * slist, void *item) -{ - if (slist->limit != 0 && slist->count >= slist->limit) - return -2; - if (slist->opts && (slist->opts->flags & SLISTF_NODUP) - && slist_indexof(slist, item) != -1) - return -3; - if (slist->capacity == slist->count) - slist_setcapacity(slist, slist->capacity + 1); - - if (slist->opts && (slist->opts->flags & SLISTF_SORT) - && slist->opts->compareitem) { - int i; - - for (i = 0; i < slist->count; i++) { - if (slist->opts->compareitem(slist, item, slist->list[i]) <= 0) { - memmove(&slist->list[i + 1], &slist->list[i], - sizeof(void *) * (slist->count - i)); - slist->list[i] = item; - break; - } - } - - if (i == slist->count) - slist->list[slist->count] = item; - } else { - slist->list[slist->count] = item; - } - - return slist->count++; -} - -/*************************************************************************/ - -/** - * Clears the list. If free is 1, the freeitem function will be called - * for each item before clearing. - * @param slist Slist Struct - * @param mustfree What is being freed - * @return void - */ -void slist_clear(SList * slist, int mustfree) -{ - if (mustfree && slist->opts && slist->opts->freeitem && slist->count) { - int i; - - for (i = 0; i < slist->count; i++) - if (slist->list[i]) - slist->opts->freeitem(slist, slist->list[i]); - } - - if (slist->list) { - free(slist->list); - slist->list = NULL; - } - slist->capacity = 0; - slist->count = 0; -} - -/*************************************************************************/ - -/** - * Deletes an item from the list, by index. Returns 1 if successful, - * 0 otherwise. - * @param slist Slist Struct - * @param index beign deleted - * @return int Returns 1 if successful, 0 otherwise. - */ -int slist_delete(SList * slist, int index) -{ - /* Range check */ - if (index >= slist->count) - return 0; - - if (slist->list[index] && slist->opts && slist->opts->freeitem) - slist->opts->freeitem(slist, slist->list[index]); - - slist->list[index] = NULL; - slist->count--; - - if (index < slist->count) - memmove(&slist->list[index], &slist->list[index + 1], - sizeof(void *) * (slist->count - index)); - - slist_setcapacity(slist, slist->capacity - 1); - - return 1; -} - -/*************************************************************************/ - -/** - * Deletes a range of entries. Return -1 if the permission was denied, - * 0 if no records were deleted, or the number of records deleted - * @param slist Slist Struct - * @param range Range to delete - * @param cb Call back function - * @param ... various args - * @return int - */ -int slist_delete_range(SList * slist, const char *crange, slist_delcheckcb_t cb, ...) -{ - int count = 0, i, n1, n2; - va_list args, preserve; - char *range = const_cast<char *>(crange); // XXX: unsafe cast - - va_start(args, cb); - - for (;;) { - n1 = n2 = strtol(range, &range, 10); - range += strcspn(range, "0123456789,-"); - - if (*range == '-') { - range++; - range += strcspn(range, "0123456789,"); - if (isdigit(*range)) { - n2 = strtol(range, &range, 10); - range += strcspn(range, "0123456789,-"); - } - } - - for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) { - - if (!slist->list[i - 1]) - continue; - - /* copy this off the stack for safety's sake --nenolod */ - VA_COPY(preserve, args); - - if (cb && !cb(slist, slist->list[i - 1], preserve)) { - va_end(preserve); - return -1; - } - - /* if it's to be freed, lets free it */ - if (slist->opts && slist->opts->freeitem) - slist->opts->freeitem(slist, slist->list[i - 1]); - slist->list[i - 1] = NULL; - - /* and release the copied list */ - va_end(preserve); - - count++; - } - - range += strcspn(range, ","); - if (*range) - range++; - else - break; - } - - /* We only really delete the items from the list after having processed - * everything because it would change the position of the items in the - * list otherwise. - */ - slist_pack(slist); - - va_end(args); - return count; -} - -/*************************************************************************/ - -/** - * Enumerates all entries of the list. If range is not NULL, will only - * enumerate entries that are in the range. Returns the total number - * of entries enumerated. - * @param slit Slist struct - * @param range Range to enum - * @param cb Call back function - * @param ... various args - * @return int - */ -int slist_enum(SList * slist, const char *crange, slist_enumcb_t cb, ...) -{ - int count = 0, i, res; - va_list args, preserve; - char *range = const_cast<char *>(crange); // XXX: unsafe cast - - va_start(args, cb); - - if (!range) { - for (i = 0; i < slist->count; i++) { - if (!slist->list[i]) { - Alog() << "SList: warning: NULL pointer in the list (?)"; - continue; - } - - /* copy off stack for safety */ - VA_COPY(preserve, args); - - res = cb(slist, i + 1, slist->list[i], preserve); - if (res < 0) { - va_end(preserve); - break; - } - - /* and release our copy */ - va_end(preserve); - - count += res; - } - } else { - int n1, n2; - - for (;;) { - res = 0; - n1 = n2 = strtol(range, &range, 10); - range += strcspn(range, "0123456789,-"); - if (*range == '-') { - range++; - range += strcspn(range, "0123456789,"); - if (isdigit(*range)) { - n2 = strtol(range, &range, 10); - range += strcspn(range, "0123456789,-"); - } - } - for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) { - if (!slist->list[i - 1]) { - Alog() << "SList: warning: NULL pointer in the list (?)"; - continue; - } - - /* copy off stack for safety */ - VA_COPY(preserve, args); - - res = cb(slist, i, slist->list[i - 1], preserve); - if (res < 0) { - va_end(preserve); - break; - } - count += res; - - /* and release our copy */ - va_end(preserve); - } - if (res < -1) - break; - range += strcspn(range, ","); - if (*range) - range++; - else - break; - } - } - - va_end(args); - - return count; -} - -/*************************************************************************/ - -/** - * Determines whether the list is full. - * @param slist Slist Struct - * @return int - */ -int slist_full(SList * slist) -{ - if (slist->limit != 0 && slist->count >= slist->limit) - return 1; - else - return 0; -} - -/*************************************************************************/ - -/** - * Initialization of the list. - * @param slist Slist Struct - * @return int - */ -void slist_init(SList * slist) -{ - memset(slist, 0, sizeof(SList)); - slist->limit = SLIST_DEFAULT_LIMIT; - slist->opts = &slist_defopts; -} - -/*************************************************************************/ - -/** - * Returns the index of an item in the list, -1 if inexistant. - * @param slist Slist Struct - * @param item Item index - * @return int - */ -int slist_indexof(SList * slist, void *item) -{ - int16 i; - void *entry; - - if (slist->count == 0) - return -1; - - for (i = 0, entry = slist->list[0]; i < slist->count; - i++, entry = slist->list[i]) { - if ((slist->opts - && slist->opts->isequal) ? (slist->opts->isequal(slist, item, - entry)) - : (item == entry)) - return i; - } - - return -1; -} - -/*************************************************************************/ - -/** - * Removes all NULL pointers from the list. - * @param slist Slist Struct - * @return void - */ -void slist_pack(SList * slist) -{ - int i; - - for (i = slist->count - 1; i >= 0; i--) - if (!slist->list[i]) - slist_delete(slist, i); -} - -/*************************************************************************/ - -/** - * Removes a specific item from the list. Returns the old index of the - * deleted item, or -1 if the item was not found. - * @param slist Slist Struct - * @param item to remove - * @return int - */ -int slist_remove(SList * slist, void *item) -{ - int index = slist_indexof(slist, item); - if (index == -1) - return -1; - slist_delete(slist, index); - return index; -} - -/*************************************************************************/ - -/** - * Sets the maximum capacity of the list - * @param slist Slist Struct - * @param capacity How large the list can be - * @return int - */ -int slist_setcapacity(SList * slist, int16 capacity) -{ - if (slist->capacity == capacity) - return 1; - slist->capacity = capacity; - if (slist->capacity) - slist->list = - static_cast<void **>(srealloc(slist->list, sizeof(void *) * slist->capacity)); - else { - free(slist->list); - slist->list = NULL; - } - if (slist->capacity < slist->count) - slist->count = slist->capacity; - return 1; -} diff --git a/src/threadengine.cpp b/src/threadengine.cpp new file mode 100644 index 000000000..ea652e1f2 --- /dev/null +++ b/src/threadengine.cpp @@ -0,0 +1,37 @@ +#include "services.h" + +ThreadEngine threadEngine; + +/** Threads constructor + */ +Thread::Thread() : Exit(false) +{ +} + +/** Threads destructor + */ +Thread::~Thread() +{ +} + +/** Sets the exit state as true informing the thread we want it to shut down + */ +void Thread::SetExitState() +{ + Exit = true; +} + +/** Returns the exit state of the thread + * @return true if we want to exit + */ +bool Thread::GetExitState() const +{ + return Exit; +} + +/** Called to run the thread, should be overloaded + */ +void Thread::Run() +{ +} + diff --git a/src/threadengine_pthread.cpp b/src/threadengine_pthread.cpp new file mode 100644 index 000000000..9d9bf160d --- /dev/null +++ b/src/threadengine_pthread.cpp @@ -0,0 +1,113 @@ +#include "services.h" + +/* Threadengine attributes used by this thread engine */ +static pthread_attr_t threadengine_attr; + +/** Entry point used for the threads + * @param parameter A Thread* cast to a void* + */ +static void *entry_point(void *parameter) +{ + Thread *thread = static_cast<Thread *>(parameter); + thread->Run(); + if (!thread->GetExitState()) + { + thread->Join(); + } + delete thread; + pthread_exit(0); +} + +/** Threadengines constructor + */ +ThreadEngine::ThreadEngine() +{ + if (pthread_attr_init(&threadengine_attr)) + { + throw CoreException("ThreadEngine: Error calling pthread_attr_init"); + } +} + +/** Threadengines destructor + */ +ThreadEngine::~ThreadEngine() +{ + pthread_attr_destroy(&threadengine_attr); +} + +/** Join to the thread, sets the exit state to true + */ +void Thread::Join() +{ + SetExitState(); + pthread_join(Handle, NULL); +} + +/** Start a new thread + * @param thread A pointer to a newley allocated thread + */ +void ThreadEngine::Start(Thread *thread) +{ + if (pthread_create(&thread->Handle, &threadengine_attr, entry_point, thread)) + { + delete thread; + throw CoreException("Unable to create thread: " + std::string(strerror(errno))); + } +} + +/** Constructor + */ +Mutex::Mutex() +{ + pthread_mutex_init(&mutex, NULL); +} + +/** Destructor + */ +Mutex::~Mutex() +{ + pthread_mutex_destroy(&mutex); +} + +/** Attempt to lock the mutex, will hang until a lock can be achieved + */ +void Mutex::Lock() +{ + pthread_mutex_lock(&mutex); +} + +/** Unlock the mutex, it must be locked first + */ +void Mutex::Unlock() +{ + pthread_mutex_unlock(&mutex); +} + +/** Constructor + */ +Condition::Condition() : Mutex() +{ + pthread_cond_init(&cond, NULL); +} + +/** Destructor + */ +Condition::~Condition() +{ + pthread_cond_destroy(&cond); +} + +/** Called to wakeup the waiter + */ +void Condition::Wakeup() +{ + pthread_cond_signal(&cond); +} + +/** Called to wait for a Wakeup() call + */ +void Condition::Wait() +{ + pthread_cond_wait(&cond, &mutex); +} + diff --git a/src/threadengine_win32.cpp b/src/threadengine_win32.cpp new file mode 100644 index 000000000..5ee2f4596 --- /dev/null +++ b/src/threadengine_win32.cpp @@ -0,0 +1,109 @@ +#include "services.h" + +/** Entry point for the thread + * @param paramter A Thread* cast to a void* + */ +static DWORD WINAPI entry_point(void *parameter) +{ + Thread *thread = static_cast<Thread *>(parameter); + thread->Run(); + if (!thread->GetExitState()) + { + thread->Join(); + } + delete thread; + return 0; +} + +/** Threadengines constructor + */ +ThreadEngine::ThreadEngine() +{ +} + +/** Threadengines destructor + */ +ThreadEngine::~ThreadEngine() +{ +} + +/** Join to the thread, sets the exit state to true + */ +void Thread::Join() +{ + SetExitState(); + WaitForSingleObject(Handle, INFINITE); +} + +/** Start a new thread + * @param thread A pointer to a newley allocated thread + */ +void ThreadEngine::Start(Thread *thread) +{ + thread->Handle = CreateThread(NULL, 0, entry_point, thread, 0, NULL); + + if (!thread->Handle) + { + delete thread; + throw CoreException("Unable to create thread: " + std::string(dlerror())); + } +} + +/** Constructor + */ +Mutex::Mutex() +{ + InitializeCriticalSection(&mutex); +} + +/** Destructor + */ +Mutex::~Mutex() +{ + DeleteCriticalSection(&mutex); +} + +/** Attempt to lock the mutex, will hang until a lock can be achieved + */ +void Mutex::Lock() +{ + EnterCriticalSection(&mutex); +} + +/** Unlock the mutex, it must be locked first + */ +void Mutex::Unlock() +{ + LeaveCriticalSection(&mutex); +} + +/** Constructor + */ +Condition::Condition() : Mutex() +{ + cond = CreateEvent(NULL, false, false, NULL); +} + +/** Destructor + */ +Condition::~Condition() +{ + CloseHandle(cond); +} + +/** Called to wakeup the waiter + */ +void Condition::Wakeup() +{ + PulseEvent(cond); +} + +/** Called to wait for a Wakeup() call + */ +void Condition::Wait() +{ + LeaveCriticalSection(&mutex); + WaitForSingleObject(cond, INFINITE); + EnterCriticalSection(&mutex); +} + diff --git a/src/tools/db-convert.c b/src/tools/db-convert.c index 0f8a35ebc..4e3d01034 100644 --- a/src/tools/db-convert.c +++ b/src/tools/db-convert.c @@ -969,7 +969,7 @@ int main(int argc, char *argv[]) fs << "OS AKILL " << user << " " << host << " " << by << " " << seton << " " << expires << " :" << reason << std::endl; free(user); free(host); free(by); free(reason); } - /* SGLINES */ + /* SNLINES */ read_int16(&capacity, f); for (i = 0; i < capacity; i++) { @@ -978,7 +978,7 @@ int main(int argc, char *argv[]) SAFE(read_string(&reason, f)); SAFE(read_int32(&seton, f)); SAFE(read_int32(&expires, f)); - fs << "OS SGLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl; + fs << "OS SNLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl; free(mask); free(by); free(reason); } /* SQLINES */ diff --git a/src/users.c b/src/users.cpp index e32363259..a1890f6c5 100644 --- a/src/users.c +++ b/src/users.cpp @@ -15,10 +15,11 @@ #include "modules.h" #include "language.h" -#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31)) -User *userlist[1024]; - -#define HASH2(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31)) +/* Hash maps used for users. Note UserListByUID will not be used on non-TS6 IRCds, and should never + * be assumed to have users + */ +user_map UserListByNick; +user_uid_map UserListByUID; int32 opcnt = 0; uint32 usercnt = 0, maxusercnt = 0; @@ -29,16 +30,12 @@ time_t maxusertime; User::User(const std::string &snick, const std::string &suid) { - User **list; - if (snick.empty()) throw "what the craq, empty nick passed to constructor"; // XXX: we should also duplicate-check here. /* we used to do this by calloc, no more. */ - this->next = NULL; - this->prev = NULL; host = hostip = vhost = realname = NULL; server = NULL; nc = NULL; @@ -47,13 +44,10 @@ User::User(const std::string &snick, const std::string &suid) this->nick = snick; this->uid = suid; - list = &userlist[HASH(this->nick)]; - this->next = *list; - if (*list) - (*list)->prev = this; - - *list = this; + UserListByNick[snick.c_str()] = this; + if (!suid.empty()) + UserListByUID[suid] = this; this->nc = NULL; @@ -72,8 +66,6 @@ User::User(const std::string &snick, const std::string &suid) void User::SetNewNick(const std::string &newnick) { - User **list; - /* Sanity check to make sure we don't segfault */ if (newnick.empty()) { @@ -82,22 +74,11 @@ void User::SetNewNick(const std::string &newnick) Alog(LOG_DEBUG) << this->nick << " changed nick to " << newnick; - if (this->prev) - this->prev->next = this->next; - else - userlist[HASH(this->nick)] = this->next; - - if (this->next) - this->next->prev = this->prev; + UserListByNick.erase(this->nick.c_str()); this->nick = newnick; - list = &userlist[HASH(this->nick)]; - this->next = *list; - this->prev = NULL; - if (*list) - (*list)->prev = this; - *list = this; + UserListByNick[this->nick.c_str()] = this; OnAccess = false; NickAlias *na = findnick(this->nick); @@ -211,7 +192,7 @@ void User::SetRealname(const std::string &srealname) this->realname = sstrdup(srealname.c_str()); NickAlias *na = findnick(this->nick); - if (na && (this->IsIdentified(true) || (!na->nc->HasFlag(NI_SECURE) && this->IsRecognized()))) + if (na && (this->IsIdentified(true) || this->IsRecognized(true))) { if (na->last_realname) delete [] na->last_realname; @@ -231,7 +212,7 @@ User::~User() Alog() << "LOGUSERS: " << this->GetMask() << (ircd->vhost ? " => " : " ") << (ircd->vhost ? this->GetDisplayedHost() : "") - << " (" << srealname << ") left the network (" << this->server->name << ")."; + << " (" << srealname << ") left the network (" << this->server->GetName() << ")."; delete [] srealname; } @@ -247,13 +228,10 @@ User::~User() { this->chans.front()->chan->DeleteUser(this); } - - if (this->prev) - this->prev->next = this->next; - else - userlist[HASH(this->nick)] = this->next; - if (this->next) - this->next->prev = this->prev; + + UserListByNick.erase(this->nick.c_str()); + if (!this->uid.empty()) + UserListByUID.erase(this->uid); NickAlias *na = findnick(this->nick); if (na) @@ -380,7 +358,7 @@ void User::Collide(NickAlias *na) snprintf(randbuf, sizeof(randbuf), "%d", getrandom16()); guestnick = std::string(Config.NSGuestNickPrefix) + std::string(randbuf); } - while (finduser(guestnick.c_str())); + while (finduser(guestnick)); notice_lang(Config.s_NickServ, this, FORCENICKCHANGE_CHANGING, guestnick.c_str()); ircdproto->SendForceNickChange(this, guestnick.c_str(), time(NULL)); @@ -434,7 +412,7 @@ void User::AutoID(const std::string &account) delete [] na->last_realname; na->last_realname = sstrdup(this->realname); na->last_seen = time(NULL); - this->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + this->SetMode(NickServ, UMODE_REGISTERED); this->UpdateHost(); check_memos(this); @@ -499,10 +477,21 @@ const bool User::IsIdentified(bool CheckNick) const } /** Check if the user is recognized for their nick (on the nicks access list) + * @param CheckSecure Only returns true if the user has secure off * @return true or false */ -const bool User::IsRecognized() const +const bool User::IsRecognized(bool CheckSecure) const { + if (CheckSecure && OnAccess) + { + NickAlias *na = findnick(this->nick); + + if (!na || !na->nc->HasFlag(NI_SECURE)) + { + return false; + } + } + return OnAccess; } @@ -514,12 +503,11 @@ void User::UpdateHost() return; NickAlias *na = findnick(this->nick); - OnAccess = false; if (na) OnAccess = is_on_access(this, na->nc); - if (na && (this->IsIdentified(true) || (!na->nc->HasFlag(NI_SECURE) && this->IsRecognized()))) + if (na && (this->IsIdentified(true) || this->IsRecognized(true))) { if (na->last_usermask) delete [] na->last_usermask; @@ -529,66 +517,13 @@ void User::UpdateHost() } } -/*************************************************************************/ - -/* Return statistics. Pointers are assumed to be valid. */ - -void get_user_stats(long *nusers, long *memuse) -{ - long count = 0, mem = 0; - int i; - User *user; - - for (i = 0; i < 1024; i++) { - for (user = userlist[i]; user; user = user->next) { - count++; - mem += sizeof(*user); - if (user->host) - mem += strlen(user->host) + 1; - if (ircd->vhost) { - if (user->vhost) - mem += strlen(user->vhost) + 1; - } - if (user->realname) - mem += strlen(user->realname) + 1; - if (user->server->name) - mem += strlen(user->server->name) + 1; - mem += (sizeof(ChannelContainer) * user->chans.size()); - } - } - *nusers = count; - *memuse = mem; -} - -/*************************************************************************/ - -/* Find a user by nick. Return NULL if user could not be found. */ - -User *finduser(const std::string &nick) -{ - User *user; - - Alog(LOG_DEBUG_3) << "finduser("<< nick << ")"; - - if (isdigit(nick[0]) && ircd->ts6) - return find_byuid(nick); - - ci::string ci_nick(nick.c_str()); - - user = userlist[HASH(nick)]; - while (user && ci_nick != user->nick) - user = user->next; - Alog(LOG_DEBUG_3) << "finduser(" << nick << ") -> " << static_cast<void *>(user); - return user; -} - /** Check if the user has a mode * @param Name Mode name * @return true or false */ const bool User::HasMode(UserModeName Name) const { - return modes[Name]; + return modes.HasFlag(Name); } /** Set a mode internally on the user, the IRCd is not informed @@ -600,7 +535,7 @@ void User::SetModeInternal(UserMode *um, const std::string &Param) if (!um) return; - modes[um->Name] = true; + modes.SetFlag(um->Name); if (!Param.empty()) { Params.insert(std::make_pair(um->Name, Param)); @@ -617,7 +552,7 @@ void User::RemoveModeInternal(UserMode *um) if (!um) return; - modes[um->Name] = false; + modes.UnsetFlag(um->Name); std::map<UserModeName, std::string>::iterator it = Params.find(um->Name); if (it != Params.end()) { @@ -694,16 +629,16 @@ void User::RemoveMode(BotInfo *bi, char ModeChar) /** Set a string of modes on a user * @param bi The client setting the mode - * @param modes The modes + * @param umodes The modes */ -void User::SetModes(BotInfo *bi, const char *modes, ...) +void User::SetModes(BotInfo *bi, const char *umodes, ...) { char buf[BUFSIZE] = ""; va_list args; std::string modebuf, sbuf; int add = -1; - va_start(args, modes); - vsnprintf(buf, BUFSIZE - 1, modes, args); + va_start(args, umodes); + vsnprintf(buf, BUFSIZE - 1, umodes, args); va_end(args); spacesepstream sep(buf); @@ -756,82 +691,74 @@ ChannelContainer *User::FindChannel(Channel *c) return NULL; } -/*************************************************************************/ - -/* Iterate over all users in the user list. Return NULL at end of list. */ - -static User *current; -static int next_index; - -User *firstuser() +/** Check if the user is protected from kicks and negative mode changes + * @return true or false + */ +bool User::IsProtected() const { - next_index = 0; - current = NULL; - while (next_index < 1024 && current == NULL) - current = userlist[next_index++]; - Alog(LOG_DEBUG) << "firstuser() returning " << (current ? current->nick : "NULL (end of list)"); - return current; -} + if (this->HasMode(UMODE_PROTECTED) || this->HasMode(UMODE_GOD)) + return true; -User *nextuser() -{ - if (current) - current = current->next; - if (!current && next_index < 1024) { - while (next_index < 1024 && current == NULL) - current = userlist[next_index++]; - } - Alog(LOG_DEBUG) << "nextuser() returning " << (current ? current->nick : "NULL (end of list)"); - return current; + return false; } -User *find_byuid(const std::string &uid) +/*************************************************************************/ + +void get_user_stats(long *nusers, long *memuse) { - User *u, *next; + long count = 0, mem = 0; + + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) + { + User *user = it->second; - u = first_uid(); - while (u) { - next = next_uid(); - if (u->GetUID() == uid) { - return u; + count++; + mem += sizeof(*user); + if (user->host) + mem += strlen(user->host) + 1; + if (ircd->vhost) + { + if (user->vhost) + mem += strlen(user->vhost) + 1; } - u = next; + if (user->realname) + mem += strlen(user->realname) + 1; + mem += user->server->GetName().length() + 1; + mem += (sizeof(ChannelContainer) * user->chans.size()); } - return NULL; + *nusers = count; + *memuse = mem; } -static User *current_uid; -static int next_index_uid; +User *finduser(const char *nick) +{ + return finduser(ci::string(nick)); +} -User *first_uid() +User *finduser(const std::string &nick) { - next_index_uid = 0; - current_uid = NULL; - while (next_index_uid < 1024 && current_uid == NULL) { - current_uid = userlist[next_index_uid++]; - } - Alog(LOG_DEBUG_2) << "first_uid() returning " - << (current_uid ? current_uid->nick : "NULL (end of list)") << " " - << (current_uid ? current_uid->GetUID() : ""); - return current_uid; + return finduser(ci::string(nick.c_str())); } -User *next_uid() +User *finduser(const ci::string &nick) { - if (current_uid) - current_uid = current_uid->next; - if (!current_uid && next_index_uid < 1024) { - while (next_index_uid < 1024 && current_uid == NULL) - current_uid = userlist[next_index_uid++]; + if (isdigit(nick[0]) && ircd->ts6) + { + user_uid_map::const_iterator it = UserListByUID.find(nick.c_str()); + + if (it != UserListByUID.end()) + return it->second; + return NULL; } - Alog(LOG_DEBUG_2) << "next_uid() returning " - << (current_uid ? current_uid->nick : "NULL (end of list)") << " " - << (current_uid ? current_uid->GetUID() : ""); - return current_uid; + + user_map::const_iterator it = UserListByNick.find(nick); + + if (it != UserListByNick.end()) + return it->second; + return NULL; } /*************************************************************************/ -/*************************************************************************/ /* Handle a server NICK command. */ @@ -862,6 +789,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const ntoa(addr, ipbuf, sizeof(ipbuf)); } + Server *serv = Server::Find(server); if (Config.LogUsers) { @@ -886,7 +814,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const << (ircd->nickvhost && vhost ? " => " : "") << (ircd->nickvhost && vhost ? vhost : "") << ") (" << logrealname << ") " << (ircd->nickip ? "[" : "") << (ircd->nickip ? ipbuf : "") << (ircd->nickip ? "]" : "") - << " connected to the network (" << server << ")."; + << " connected to the network (" << serv->GetName() << ")."; delete [] logrealname; } @@ -894,7 +822,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const user = new User(nick, uid ? uid : ""); user->SetIdent(username); user->host = sstrdup(host); - user->server = findserver(servlist, server); + user->server = serv; user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); @@ -914,20 +842,11 @@ User *do_nick(const char *source, const char *nick, const char *username, const if (MOD_RESULT == EVENT_STOP) return finduser(nick); - check_akill(nick, username, host, vhost, ipbuf); - - if (ircd->sgline) - check_sgline(nick, realname); - - if (ircd->sqline) - check_sqline(nick, 0); - - if (ircd->szline && ircd->nickip) - check_szline(nick, ipbuf); - - if (Config.LimitSessions && !is_ulined(server)) + if (Config.LimitSessions && !serv->IsULined()) add_session(nick, host, ipbuf); + XLineManager::CheckAll(user); + /* User is no longer connected, return */ if (!finduser(nick)) return NULL; @@ -937,11 +856,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const else { /* An old user changing nicks. */ - if (ircd->ts6) - user = find_byuid(source); - - if (!user) - user = finduser(source); + user = finduser(source); if (!user) { Alog() << "user: NICK from nonexistent nick " << source; @@ -954,8 +869,8 @@ User *do_nick(const char *source, const char *nick, const char *username, const { const char *logrealname = normalizeBuffer(user->realname); Alog() << "LOGUSERS: " << user->nick << " (" << user->GetIdent() << "@" << user->host - << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") (" - << logrealname << ") " << "changed nick to " << nick << " (" << user->server->name << ")."; + << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") (" + << logrealname << ") " << "changed nick to " << nick << " (" << user->server->GetName() << ")."; if (logrealname) delete [] logrealname; } @@ -1002,7 +917,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const if (ircd->sqline) { - if (!is_oper(user) && check_sqline(user->nick.c_str(), 1)) + if (!is_oper(user) && SQLine->Check(user)) return NULL; } } @@ -1055,9 +970,8 @@ void do_quit(const char *source, int ac, const char **av) delete [] na->last_quit; na->last_quit = *av[0] ? sstrdup(av[0]) : NULL; } - if (Config.LimitSessions && !is_ulined(user->server->name)) { + if (Config.LimitSessions && !user->server->IsULined()) del_session(user->host); - } FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, *av[0] ? av[0] : "")); delete user; } @@ -1088,7 +1002,7 @@ void do_kill(const std::string &nick, const std::string &msg) delete [] na->last_quit; na->last_quit = !msg.empty() ? sstrdup(msg.c_str()) : NULL; } - if (Config.LimitSessions && !is_ulined(user->server->name)) { + if (Config.LimitSessions && !user->server->IsULined()) { del_session(user->host); } delete user; @@ -1097,18 +1011,6 @@ void do_kill(const std::string &nick, const std::string &msg) /*************************************************************************/ /*************************************************************************/ -/* Is the given user protected from kicks and negative mode changes? */ - -int is_protected(User * user) -{ - if (user && user->HasMode(UMODE_PROTECTED)) - return 1; - - return 0; -} - -/*************************************************************************/ - /* Is the given nick an oper? */ int is_oper(User * user) @@ -1308,14 +1210,14 @@ void UserSetInternalModes(User *user, int ac, const char **av) { ++opcnt; if (Config.WallOper) - ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 is now an IRC operator.", user->nick.c_str()); + ircdproto->SendGlobops(OperServ, "\2%s\2 is now an IRC operator.", user->nick.c_str()); } else --opcnt; break; case UMODE_REGISTERED: if (add && !user->IsIdentified()) - user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); + user->RemoveMode(NickServ, UMODE_REGISTERED); break; case UMODE_CLOAK: case UMODE_VHOST: |