1
0
mirror of https://github.com/anope/anope.git synced 2026-06-20 04:24:45 +02:00

Compare commits

...

165 Commits

Author SHA1 Message Date
Adam f082530f89 Anope 1.9.6 Release 2012-02-03 15:19:09 -05:00
Adam b906656caa Update version.log 2012-02-03 15:18:27 -05:00
Adam 378ae4c4f1 Regenerate language files 2012-02-03 15:18:06 -05:00
Adam ce2a0f72d4 Fixed a memory leak in m_ldap 2012-01-31 16:19:47 -05:00
Adam be5ba495f9 Not sure what I was thinking here 2012-01-31 15:44:04 -05:00
Adam b4f27da51c Bug #1365 - Fixed nickserv/confirm syntax for services opers 2012-01-31 15:35:51 -05:00
Adam d09a30295b Also refuse to load memoserv modules if memoserv isn't loaded 2012-01-26 17:04:59 -05:00
Adam 0f909273e1 Added two common warning messages on Windows to ignore 2012-01-25 16:13:38 -05:00
Adam 52eaa7d6d6 Windows 2012-01-25 15:48:07 -05:00
Adam e88e37c59b Add some checks in ms_* to make sure memoserv really exists 2012-01-24 18:28:37 -05:00
Adam f10f49d6fc Added missing expires column in /os akill view 2012-01-24 16:42:21 -05:00
Adam d06cdaab29 Fixed os_ignore to check against users real IPs, not to match against opers, and check for expired ignores on /os ignore list 2012-01-24 16:35:54 -05:00
Adam fc20bd7b22 Add tracking for Unreal's usermode +I 2012-01-24 16:03:44 -05:00
DukePyrolator b3d9412452 added a french INSTALL file, thanks to MacLeod for translating 2012-01-22 17:49:23 +01:00
Adam 98feb1b76d Cleaned up bs_kick and fixed amsg kicker 2012-01-21 00:50:48 -05:00
lethality 94c302baf3 Fixed param check from last commit 2012-01-20 20:50:36 +00:00
lethality cdb6bb8ec2 Updated DEFCON and fixed Defcons disabling of the removed mlock command 2012-01-20 17:50:09 +00:00
lethality a851f849df Corrected some incorrect English 2012-01-20 15:03:49 +00:00
Adam a270a13010 Fixed crash from last commit 2012-01-15 02:59:09 -05:00
Adam 964d63cdac Improve on db_sql_live_read 2012-01-15 01:47:31 -05:00
lethality f38faedbda Fixed an incorrect crash-causing response when an invalid option is specified in botservs kickers 2012-01-14 15:58:51 +00:00
Adam c462a69b7d Only match users nicks against access list entries if the entry is a mask... accidentally removed from an earlier fix for #1368 2012-01-13 15:37:17 -05:00
Adam 14a2c9cec0 Fixed loading db_sql_live_read's configuration values on startup 2012-01-11 19:04:40 -05:00
Adam a52ed70ea0 Don't ever attempt to process CTCPs as regular messages 2012-01-10 17:58:56 -05:00
Adam 7c03e60299 Removed this "valid" ip check in cidr::cidr, is wrong for IPv6 and ::pton checks this anyway using inet_pton. Also fixed a comment Robby broke in chanserv.conf 2012-01-10 17:53:48 -05:00
Adam 1e9d88af01 Add support for Unreals extban ~a: 2012-01-10 17:06:08 -05:00
Adam 815e140ecf Fixed loading akill reasons 2012-01-08 19:42:48 -05:00
Adam f8245574dc Fixed topic lock on inspircd 2012-01-08 18:14:07 -05:00
Adam 830c5ca725 Cleanup of cs_tban 2012-01-07 16:21:31 -05:00
Robby 9e71394127 Cleaned up a lot of log messages, help replies, fixed cs_tban, and other small fixes 2012-01-07 04:10:30 -05:00
Adam dd64eac782 Fixed users not being able to delete their own access with /cs access when using numbers, and clean up cs_xop slightly 2012-01-07 03:44:43 -05:00
Adam 4204ece7a8 Updated Copyright to 2012 2012-01-02 21:28:24 -05:00
Adam 60a5cc1a61 Bug #1369 - Fixed os_svsnick to allow changing the case of a users' nick 2011-12-31 03:04:44 -05:00
Adam 20aa4e85ce Bug #1368 - check all members of a users gruop against the access list 2011-12-31 01:33:32 -05:00
Adam f1b05acf26 Fixed this back now unreal sends 0 for non logged in users 2011-12-28 12:49:04 -05:00
Adam a4bf770a49 Added ESVID support to unreal32
Also fixes a crash due to unreal's ESVID change when users connect.
2011-12-28 04:31:44 -05:00
Adam 150831c1a6 Made capab management a bit simplier 2011-12-27 23:11:14 -05:00
Adam 1a4157b7f4 Add DT_ALLOW_EMPTY config flag, allow fantasychars to be empty 2011-12-23 12:29:30 -05:00
Adam 3bcb285690 Somehow these two modules got mixed up.. 2011-12-22 03:46:35 -05:00
Adam 704dbe27bf Updated /bs info output and note db_sql can truncate entire databases 2011-12-20 18:38:37 -05:00
Adam bbddf50c9d Fixed botserv kickers 2011-12-19 17:13:38 -05:00
Adam e5851addd6 Fixed saving databases with MySQL when shut down by SIGINT 2011-12-19 16:07:28 -05:00
Adam 03119f2aa9 Made m_dnsbl ban IPs not hostnames 2011-12-19 15:41:14 -05:00
Adam 45fc3ce1c4 Fixed formatting of many lists and INFO outputs 2011-12-19 15:37:15 -05:00
lethality d320c73f23 Fixed entry messages not displaying. 2011-12-17 10:30:13 +00:00
lethality ca8ce89de4 Fixed a slight error in email registration/resend and some minor typos. 2011-12-17 02:06:53 +00:00
Adam c88a751eab Add privilege ranks to determine how powerful privileges are 2011-12-15 02:29:13 -05:00
Adam 9ea030d060 Fixed access comparators 2011-12-15 01:14:13 -05:00
Adam ad14c8145b Update channel last used times when founders use the channel, too 2011-12-12 15:37:08 -05:00
Adam 255a8da347 Added oper:require_oper configuration option 2011-12-12 15:26:59 -05:00
Adam 4211dcf6f9 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-12-11 17:03:33 -05:00
Adam 3c5337fb8a Fixed translating messages with varargs sent directly to users, too 2011-12-11 17:01:56 -05:00
lethality d2f788c61e Added K to vhost_chars... 2011-12-11 05:17:19 +00:00
Adam fa54d5acb7 Fixed a memory leak in m_sqlite 2011-12-08 17:29:17 -05:00
Adam aeefe1650e Bug #1364 - fixed crash in /cs kick 2011-12-05 11:52:40 -05:00
Naram Qashat c80e7844b7 Attempt to fix issue with modules having their link libraries in the wrong order. 2011-12-03 19:17:41 -05:00
lethality 620c08bd7a Fixed some more errors in sql live-write, hopefully the last. 2011-11-25 23:12:23 +00:00
lethality 23a92709c0 Fixed a crash in ns saset when using mysql-write module 2011-11-25 23:10:26 +00:00
Adam cef3eb78df Remove send_cmd and replace it with a stringstream 2011-11-25 00:44:31 -05:00
Adam 12d0a7302f Merge branch '1.9' of ssh://anope.git.sf.net/gitroot/anope/anope into 1.9 2011-11-21 16:24:45 -05:00
Adam 0dd85f7761 Fixed not translating messages using varargs 2011-11-21 16:17:17 -05:00
Naram Qashat 51d6e8ebfb CMake handles strings and lists differently, so this should hopefully finally fix the linking issue. 2011-11-20 18:41:46 -05:00
Naram Qashat 3f14882992 Apparently pstdint.h was NOT included way back with commit 377a7a9 to use something similar to stdint.h 2011-11-20 18:34:13 -05:00
Naram Qashat 5a17b060fe Really fix linking in libraries (even if gettext isn't found on *nix), and a minor nitpick about the leading spaces on LINK_LIBS. 2011-11-20 18:32:47 -05:00
Naram Qashat bf8e4ac714 Attempt to fix where link libraries are set when compiling to fix failed builds on systems that require -ldl. 2011-11-20 16:09:59 -05:00
Adam 781ed11ba8 Allow services operators to modify other users access list 2011-11-20 15:31:01 -05:00
Adam 6f8f7491db Allow kicking and banning by mask 2011-11-18 16:20:17 -05:00
Adam c43cdf438f Added operserv/logout 2011-11-18 11:22:01 -05:00
Adam 8374211239 Allow having multiple fantasy characters 2011-11-18 00:36:54 -05:00
Adam 69dfc729e9 Fixed storing mode locks 2011-11-17 12:46:18 -05:00
Adam 5281282a61 Fixed compile error 2011-11-16 16:22:58 -05:00
Adam 503eb42e40 Made looking up a level for a nonexistant privilege debugg log a warning, not abort 2011-11-15 16:30:31 -05:00
Adam 38d90c76e0 Fixed loading ssl certs for users 2011-11-15 16:27:32 -05:00
Adam 1356498320 Prevent locking mode Z on unrealircd 2011-11-15 16:22:02 -05:00
Adam 9ed203c0cb Fixed crash on shutdown & a compiler warning 2011-11-15 16:16:38 -05:00
Adam b5ff856f47 Windows 2011-11-08 17:29:16 -05:00
Adam 97b9055f92 Remove xlines from the IRCd aswell as from our list when the clear command is used, and fixed adding timed Zlines to inspircd 2011-11-05 15:05:15 -04:00
Adam 5f0b9338dc Set proper expirys on ZLines if the IRCd supports it 2011-11-05 00:11:49 -04:00
Adam b3194a10c5 Updated Changes 2011-11-04 19:39:27 -04:00
Adam d01f4ea3ce Allow /os userlist to match host and ip too 2011-11-04 18:04:12 -04:00
Adam a42cafbf69 Store flags for memos, fixed the expiring very soon message, fixed /os session view when a session exception is added at a lower limit than th default 2011-11-04 17:55:14 -04:00
Adam 066e5b3fc0 Delete all tables before flushing not just ones we know about 2011-11-04 02:28:21 -04:00
Adam 09dba47653 Added an assignment operator for Serializable because some STL containers use it which causes iterators to become invalidated 2011-11-03 18:59:51 -04:00
Adam ca33ac608d Bug #1354 - Allow mode chars to be used for channel prefixs in services.conf 2011-11-03 02:28:29 -04:00
Adam 302989bed1 Clarify the message when users try to lock modes they don't have access to lock 2011-11-01 01:11:26 -04:00
Adam 22b7d9fbee Added a copy constructor to dynamic_reference to allow references to reference other references correctly 2011-11-01 00:15:28 -04:00
Adam 9dd71c427d Fixed the signal/fork/wait mess hopefully once and for all. fork() did not copy kqueue descriptors on freebsd which caused problems 2011-10-29 21:16:50 -04:00
Naram Qashat 655c1cc1f7 Fix a few warnings that only showed up with gcc 3.4.6 here (sadly, there is one on every file about anonymous variadic macros that I can't get rid of). 2011-10-27 18:21:49 -04:00
Adam d9333e02fa Clear flags before rebuilding them from the databases. Fixes bug #1351 where default flags would always be set when unserializing objects. 2011-10-27 18:01:56 -04:00
Adam 39ac438b8d Ignore sigchld/usr2 sent to the child process after fork 2011-10-27 15:09:31 -04:00
Adam 0761a4a692 Bug #1350 + other related fixes 2011-10-27 14:46:20 -04:00
Adam 66ca256cfc Fixed loading exceptions in db_plain 2011-10-27 13:50:32 -04:00
lethality 961bb6e27e Fixed some typos/errors in the example configs comments. 2011-10-27 00:13:00 +01:00
Adam b14f5ea884 Fixed accidentally clearing botmodes when joins are sent 2011-10-26 16:52:00 -04:00
Adam bf66336e2c Bug #1347, fixed incorrect param parsing in cs_set_misc 2011-10-26 15:29:45 -04:00
Adam c79a575452 Bug #1348 - Fixed /cs entrymsg list 2011-10-26 15:17:05 -04:00
Adam 8334128680 Removed the old unordered_map code 2011-10-26 14:31:58 -04:00
Adam 7c62de1f27 Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9 2011-10-24 16:37:29 -04:00
Naram Qashat 377a7a968b Fixed bug #1349 (m_sqlite compiles without error under FreeBSD), as well as use C99's stdint.h (or cstdint if available) to get (u)intX_t types instead of our stupid typedefs. pstdint.h included in case there is no cstdint or stdint.h available. 2011-10-24 16:32:29 -04:00
Adam ccf29c0134 Fixed the capab parser to parse capab tokens prefixed with :. Fixes not detecting quitstorm support on ratbox 2011-10-24 13:19:51 -04:00
Adam d0513d6506 A few minor fixups 2011-10-22 16:11:26 -04:00
Adam f4a0bdd54d Added our own eventfd test for openvz machines which have eventfd but can not be used 2011-10-22 12:45:55 -04:00
Adam 3e2ac3640d Bug #1343 - don't allow recovering and ghosting enforcers 2011-10-22 11:35:31 -04:00
Adam c8b3809fc9 Added akill ids 2011-10-22 11:21:21 -04:00
Adam ad2ef75cbe Fixed a race condition with installing signal handlers and forking 2011-10-22 11:20:50 -04:00
Adam 6ce9010324 Fixed extracting multiple words from our serializable stringstream 2011-10-21 18:01:51 -04:00
Adam d0afc8c509 Added m_rewrite 2011-10-21 00:21:34 -04:00
Adam 230b3bc884 Only fork if we are at term 2011-10-20 13:38:37 -04:00
Adam 1cfb630ede Fixed a crash in clearusers 2011-10-20 11:54:56 -04:00
Adam d16f9620d5 Bug #1342 - fixed tracking chmodes in bahamuts sjoin 2011-10-19 12:59:16 -04:00
Adam fc16746352 Prevent chankill from akilling my clients 2011-10-18 12:18:18 -04:00
Adam eb5b5f97d1 Fixed compile errors on release build 2011-10-18 12:06:51 -04:00
Adam faea45245d Reorder some stuff in Init & the ts6 proto mods to fix weirdness from bots being introduced by 3rd party modules 2011-10-18 01:48:05 -04:00
Adam 2c614d5aab Fixed up anoperc to work with the newer startup method 2011-10-15 02:08:52 -04:00
Adam 89b4be681d Fixed crash on /os oper del 2011-10-15 00:54:32 -04:00
Adam 28ca0e1007 Fork earlier in startup to prevent it messing up threads, if there are any 2011-10-14 22:07:13 -04:00
Adam 2504af7d0f Fixed os_forbid adds reason if no expiry is given 2011-10-14 12:53:28 -04:00
Adam ddc3c2f38c Added options:nonicknameownership config option 2011-10-14 12:20:07 -04:00
Adam 53275c362c Don't add new levels to existing channels default, screws with stuff when the config is reloaded 2011-10-11 02:50:37 -04:00
Adam f3f6727cdd Bug #1337 2011-10-11 00:09:26 -04:00
Adam 4681e3a0ef Allow chanserv/suspend to take an expiry time 2011-10-10 17:19:06 -04:00
Adam 80f4f317b2 Put serialized_items on the heap to prevent weird crashes on shutdown from the list being destructed before members in it 2011-10-10 15:04:23 -04:00
Adam 9f3d735d9d Allow nickserv/suspend to take an expiry time 2011-10-10 14:16:59 -04:00
Adam 0e012f73d4 Check for being at terminal before forking 2011-10-09 21:29:34 -04:00
Adam 9f850334a1 Give more verbose messages on startup 2011-10-09 02:52:13 -04:00
Adam af273e3da5 Store flags for objects, also fixes bug #1333 2011-09-25 15:34:56 -04:00
Adam 1f3e96f4ad Made channel privileges case insensitive 2011-09-25 14:42:09 -04:00
Adam e7ba639beb Remove opnotice from example configs 2011-09-25 14:38:21 -04:00
Adam 1f2399de36 Added a new database format and sqlite support. Also moved db-convert to a module. 2011-09-25 04:19:15 -04:00
Adam 43201ead95 Fixed /os reload doing weird things to service channels, and allow setting modes by clients on burst 2011-09-19 18:35:40 -04:00
Adam 7dce64e540 Fixed missing _ in cs_appendtopic 2011-09-19 13:14:20 -04:00
Adam 1184eb59c5 Allow OnPreHelp to stop processing 2011-09-19 13:12:52 -04:00
Adam 4c2a4929ea Call fantasy events even if the commands for them don't exist 2011-09-19 12:36:52 -04:00
Adam be77a7e27e Bug #1334 - fixed crash on /os oper info 2011-09-19 12:29:54 -04:00
Adam 934723faa5 LOG_COMMAND must now always give a valid command 2011-09-19 12:14:02 -04:00
Adam f07295cc78 Bug #1332 - Fixed ValidateUser to not require secure off to disable nickserv kill 2011-09-16 14:07:33 -04:00
Adam 26c1d67556 Fixed compile errors & warnings from 1.9.6 to 1.9 merge 2011-09-10 16:27:10 -04:00
Adam 3d5889c308 Updated channel flag names to remove LOGCHAN 2011-09-10 16:08:58 -04:00
Adam 213c1c4860 Changed msgmerge to not use -E.. it will escape all of some languages and mess up poedit etc. Keep it in xgettext for the bold/underline characters. 2011-09-10 02:42:18 -04:00
Adam 63cb8ca24c Moved signal/thread/mode checking to use signal pipes 2011-09-10 02:06:31 -04:00
Adam dc5d1fa21c Made ChanServ privileges configurable 2011-09-10 02:06:31 -04:00
Adam 563d158e49 Allow Config to install cmake 2011-09-10 02:06:31 -04:00
Adam 1478b5bbd7 Added chanserv/log 2011-09-10 02:06:29 -04:00
Adam 19e0b87aa1 Removed /bs set msg 2011-09-10 02:05:56 -04:00
Adam 17ea4ed8f5 Fixed service_reference to work correctly with external classes 2011-09-10 02:05:03 -04:00
Adam feaef7cc4a Allow services to register or unregister themselves 2011-09-10 02:05:03 -04:00
Adam c6d3fbdfab Added kqueue 2011-09-10 02:05:02 -04:00
Adam 700a585b1b Allow modules to add their own channel levels 2011-09-10 02:05:00 -04:00
Adam 62752db4c4 Rewrote mlock saving/loading code to not use this silly extensible hack 2011-09-10 01:58:39 -04:00
Adam f025d1b495 Made service_reference type safe 2011-09-10 01:58:38 -04:00
Adam 8c4417cad1 Removed opnotice 2011-09-10 01:58:38 -04:00
Adam d4db2b84f2 Made the IsValidHost checks configurable 2011-09-10 01:58:38 -04:00
Adam bb8e04c835 Added oper:host and oper:vhost 2011-09-10 01:58:35 -04:00
Adam b504791bad Cleaned up the dns engine, and fixed sometimes parsing multiple answer queries incorrectly 2011-09-10 01:55:37 -04:00
Adam d5749c11f3 Fixed eventfd pipeengine to not add the same socket twice 2011-09-10 01:55:37 -04:00
Adam f54ab5e2ca Squash merge of 1.9 to 1.9.6 2011-09-10 01:55:29 -04:00
Adam 1e45019f8a Added m_proxyscan 2011-09-10 01:55:11 -04:00
Adam 2eb708e5ad Cleaned up some of the socket code, cleaned up the pipe engines, added support for binary sockets, and cleaned up the asynch connect/accept code 2011-09-10 01:55:09 -04:00
Adam 4fcb371bc8 Track what "level" channel status modes are, which allows us to have chanserv/mode determine if a status mode can be set by users better 2011-09-10 01:52:59 -04:00
Adam 6401d93b8e Added chanserv/up and chanserv/down 2011-09-10 01:52:59 -04:00
Adam 8a9a39c065 Renamed the core pseudoclient modules to match their names 2011-09-10 01:52:59 -04:00
Adam 13e8b26989 Made email messages sent by services configurable 2011-09-10 01:52:59 -04:00
Adam 8a6d6577bd Removed log:inhabitlogchannel and replaced it with service:channels 2011-09-10 01:52:46 -04:00
Adam 4a7ba7ef4c Removed SZLine. Instead, have AKILL determine whether or not a ZLINE should be set. 2011-09-10 00:58:35 -04:00
Adam 2b5d9f349f Bump for 1.9.6 git 2011-09-10 00:54:29 -04:00
336 changed files with 64377 additions and 82589 deletions
+14 -17
View File
@@ -238,7 +238,7 @@ if(MSVC)
string(REPLACE "/GX " "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REPLACE "/W3 " "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# Set the compile flags to have warnings on the max setting (but disable a few annoying ones), exception handling turned on, the proper defines
set(CXXFLAGS "${CXXFLAGS} /W4 /wd4100 /wd4251 /wd4706 /wd4800 /wd4996 /EHs")
set(CXXFLAGS "${CXXFLAGS} /W4 /wd4100 /wd4127 /wd4250 /wd4251 /wd4355 /wd4706 /wd4800 /wd4996 /EHs")
add_definitions(-DMSVCPP -D_CRT_SECURE_NO_WARNINGS)
# Otherwise, we're not using Visual Studio
else(MSVC)
@@ -248,7 +248,7 @@ else(MSVC)
if(UNIX)
set(CXXFLAGS "${CXXFLAGS} -ansi -pedantic")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CXXFLAGS "${CXXFLAGS} -fno-leading-underscore")
set(CXXFLAGS "${CXXFLAGS} -Wno-long-long -fno-leading-underscore")
endif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# If we aren't on a *nix system, we are using MinGW
else(UNIX)
@@ -261,7 +261,7 @@ endif(MSVC)
# If CMake has found that the given system requires a special library for dl* calls, include it with the linker flags
if(CMAKE_DL_LIBS)
set(LDFLAGS "${LDFLAGS} -l${CMAKE_DL_LIBS}")
append_to_list(LINK_LIBS ${CMAKE_DL_LIBS})
endif(CMAKE_DL_LIBS)
# Under MinGW, the -shared flag isn't properly set in the module-specific linker flags, add it from the C flags for shared libraries
@@ -297,12 +297,12 @@ if(NOT MSVC)
# Check if socket is within the socket library (if the library exists), and add it to the linker flags if needed
check_library_exists(socket socket "" HAVE_SOCKET_LIB)
if(HAVE_SOCKET_LIB)
set(LDFLAGS "${LDFLAGS} -lsocket")
append_to_list(LINK_LIBS socket)
endif(HAVE_SOCKET_LIB)
# Check if inet_addr is within the nsl library (if the library exists), and add it to the linker flags if needed
check_library_exists(nsl inet_addr "" HAVE_NSL_LIB)
if(HAVE_NSL_LIB)
set(LDFLAGS "${LDFLAGS} -lnsl")
append_to_list(LINK_LIBS nsl)
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)
@@ -329,28 +329,25 @@ if(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINF
endif(CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
# Check for the existance of the following include files
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
check_include_file(cstdint HAVE_CSTDINT)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(strings.h HAVE_STRINGS_H)
check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
# Check for the existance of the following functions
check_function_exists(setgrent HAVE_SETGRENT)
check_function_exists(strcasecmp HAVE_STRCASECMP)
check_function_exists(stricmp HAVE_STRICMP)
check_function_exists(umask HAVE_UMASK)
check_function_exists(eventfd HAVE_EVENTFD)
check_function_exists(epoll_wait HAVE_EPOLL)
check_function_exists(poll HAVE_POLL)
check_function_exists(kqueue HAVE_KQUEUE)
# Check for the existance of the following types
check_type_size(uint8_t UINT8_T)
check_type_size(u_int8_t U_INT8_T)
check_type_size(int16_t INT16_T)
check_type_size(uint16_t UINT16_T)
check_type_size(u_int16_t U_INT16_T)
check_type_size(int32_t INT32_T)
check_type_size(uint32_t UINT32_T)
check_type_size(u_int32_t U_INT32_T)
# Check if eventfd works
try_run(EVENTFD_TEST_RUN_RESULT EVENTFD_TEST_COMPILE_RESULT ${CMAKE_CURRENT_BINARY_DIR} ${Anope_SOURCE_DIR}/cmake/eventfd_test.cpp)
set(HAVE_EVENTFD FALSE)
if (EVENTFD_TEST_COMPILE_RESULT AND EVENTFD_TEST_RUN_RESULT EQUAL 1)
set(HAVE_EVENTFD TRUE)
endif(EVENTFD_TEST_COMPILE_RESULT AND EVENTFD_TEST_RUN_RESULT EQUAL 1)
# Strip the leading and trailing spaces from the compile flags
if(CXXFLAGS)
+38 -4
View File
@@ -151,15 +151,49 @@ while [ $# -ge 1 ] ; do
shift 1
done
###########################################################################
# Check for CMake and (optionally) install it
###########################################################################
which cmake > /dev/null
if [ $? -ne 0 ] ; then
clear
echo "Anope requires CMake 2.4 or newer to be configured, which can"
echo "be downloaded at http://www.cmake.org/. If you have installed"
echo "CMake already, ensure it is in your PATH environment variable."
exit 0
if exists "cmake-bin" ; then :
else
echo "Anope requires CMake 2.4 or newer, which can be downloaded at http://cmake.org"
echo "If you have installed CMake already, ensure it is in your PATH environment variable."
if [ `uname` = "Linux" ] ; then
echo ""
echo "Config can attempt to install CMake for you now, which"
echo "will take approximately 50 MB of disk space."
echo "Would you like to install CMake now?"
echo2 "[y] "
read YN
if [ "$YN" = "n" ] ; then
exit 0
fi
echo "Downloading CMake... this may take a minute or two."
wget -q http://anope.org/cmake/linux-i386.php -O cmake-bin.tar.gz
if [ $? -ne 0 ] ; then
rm -f cmake-bin.tar.gz
echo "Unable to download CMake"
exit 0
fi
mkdir -p cmake-bin
tar zxf cmake-bin.tar.gz -C cmake-bin
rm -f cmake-bin.tar.gz
echo "Done!"
else
exit 0
fi
fi
CMAKE_BIN=`find cmake-bin -name cmake`
CMAKE_BIN="`pwd`/`dirname $CMAKE_BIN`"
PATH="$PATH:$CMAKE_BIN"
fi
###########################################################################
+1 -1
View File
@@ -479,7 +479,7 @@ macro(calculate_libraries SRC SKIP SRC_LDFLAGS EXTRA_DEPENDS)
endforeach(LIBRARY_PATH)
# Iterate through libraries and add them to the linker flags
foreach(LIBRARY ${LIBRARIES})
set(THIS_LDFLAGS "${THIS_LDFLAGS} -l${LIBRARY}")
append_to_list(EXTRA_DEPENDENCIES "${LIBRARY}")
endforeach(LIBRARY)
set(${SRC_LDFLAGS} "${THIS_LDFLAGS}")
set(${EXTRA_DEPENDS} "${EXTRA_DEPENDENCIES}")
+8
View File
@@ -0,0 +1,8 @@
#include <sys/eventfd.h>
int main()
{
int i = eventfd(0, EFD_NONBLOCK);
return i >= 0 ? 1 : 0;
}
+1 -1
View File
@@ -1,6 +1,6 @@
# Only install example.chk and example.conf from this directory
# NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file)
set(DATA example.chk tables.sql botserv.example.conf example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf)
set(DATA example.chk botserv.example.conf example.conf hostserv.example.conf modules.example.conf operserv.example.conf chanserv.example.conf global.example.conf memoserv.example.conf nickserv.example.conf)
install(FILES ${DATA}
DESTINATION data
)
+12 -3
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for BotServ.
*/
module { name = "bs_main" }
module { name = "botserv" }
/*
* Configuration for BotServ provided by bs_main.
@@ -121,11 +130,11 @@ botserv
#casesensitive = yes
/*
* Defines the prefix for fantasy commands in channels. This character will have to be prepended
* Defines the prefixs for fantasy commands in channels. One of these characters will have to be prepended
* to all fantasy commands. If you choose "!", for example, fantasy commands will be "!kick",
* "!op", etc. This directive is optional, if left out, the default fantasy character is "!".
*/
#fantasycharacter = "!"
#fantasycharacter = "!."
}
/*
+659 -103
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for ChanServ.
*/
module { name = "cs_main" }
module { name = "chanserv" }
/*
* Configuration for ChanServ provided by cs_main.
@@ -65,7 +74,6 @@ chanserv
*
* The options are:
* - keeptopic: Retain topic when the channel is not in use
* - opnotice: Send a notice when OP/DEOP commands are used
* - peace: Disallow users from kicking or removing modes from others who are of the same
* access level or superior
* - private: Hide the channel from ChanServ's LIST command
@@ -163,98 +171,626 @@ chanserv
* This directive is optional.
*/
#opersonly = yes
}
/*
* ChanServ levels configuration, for use with cs_access.
*
* These levels are used by the chanserv/access access system.
* The levels configured below will be used as a default by newly registered channels.
*
* The level "founder" is a special level that means anyone with the level_founder permission
* can use (which of course defaults to "founder"). Anyone with the founder level permission in
* a channel can do anything in the channel.
*
* The level "disabled" is a special level that means the level is disabled, even from people
* with founder level access.
*/
level_change = 10
level_list = 1
level_akick = 10
level_assign = "founder"
level_autohalfop = 4
level_autoop = 5
level_autoowner = 9999
level_autoprotect = 10
level_autovoice = 3
level_badwords = 10
level_ban = 4
level_fantasia = 3
level_founder = "founder"
level_getkey = 5
level_greet = 5
level_halfop = 5
level_halfopme = 4
level_info = 9999
level_invite = 5
level_kick = 4
level_memo = 10
level_mode = 5
level_nokick = 1
level_opdeop = 5
level_opdeopme = 5
level_owner = "founder"
level_ownerme = 9999
level_protect = 9999
level_protectme = 10
level_say = 5
level_signkick = 9999
level_set = 9999
level_topic = 5
level_unban = 4
level_voice = 4
level_voiceme = 3
/*
* ChanServ privilege configuration.
*
* ChanServ privileges are used to determine who has what access in channels. By default the core has its own
* set of levels it uses for various ChanServ commands, which are defined below. Privilege ranks are used to
* determine how powerful privileges are relative to each other, which is used by Anope to determine who has greater
* access in a channel.
*
* If you loaded cs_access, you may define a level for the privilege, which is used by chanserv/access and chanserv/levels.
* The levels defined will be used as the default levels for newly registered channels.
* The level "founder" is a special level which means anyone with the privilege FOUNDER on the channel
* has that permission. Additionally, the level "disabled" means that no one can use the privilege, including founders.
*
* If you loaded cs_flags, you may define a flag associated with that privilege for use in chanserv/flags.
*
* Defining new privileges here is not useful unless you have a module (eg, a third party one) made to check for
* the specific level you are defining.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
*/
/*
* ChanServ flags configuration, for use with cs_flags.
*
* These flags are used by the chanserv/flags access system.
*/
flag_change = "f"
flag_list = "l"
flag_akick = "K"
flag_assign = "s"
flag_autohalfop = "H"
flag_autoop = "O"
flag_autoowner = "Q"
flag_autoprotect = "A"
flag_autovoice = "V"
flag_badwords = "k"
flag_ban = "b"
flag_fantasia = "c"
flag_founder = "F"
flag_getkey = "G"
flag_greet = "g"
flag_halfop = "h"
flag_halfopme = "h"
flag_info = "I"
flag_invite = "i"
flag_kick = "k"
flag_memo = "m"
flag_mode = "s"
flag_nokick = "N"
flag_opdeop = "o"
flag_opdeopme = "o"
flag_owner = "q"
flag_ownerme = "q"
flag_protect = "a"
flag_protectme = "a"
flag_say = "B"
flag_set = "s"
flag_signkick = "K"
flag_topic = "t"
flag_unban = "u"
flag_voice = "v"
flag_voiceme = "v"
/*
* ACCESS_CHANGE privilege.
*
* Used by chanserv/access, chanserv/flags and chanserv/xop.
*
* Users with this permission can modify the permissions of others.
*/
privilege
{
name = "ACCESS_CHANGE"
desc = "Allowed to modify the access list"
rank = 290
level = 10
flag = "f"
}
/*
* ACCESS_LIST privilege.
*
* Used by chanserv/access, chanserv/flags, and chanserv/xop.
*
* Users with this permission can view the access list of channels.
*/
privilege
{
name = "ACCESS_LIST"
desc = "Allowed to view the access list"
rank = 10
level = 10
flag = "f"
}
/*
* AKICK privilege.
*
* Used by chanserv/akick and chanserv/enforce.
*
* Users with this permission can modify the AKICK list.
*/
privilege
{
name = "AKICK"
desc = "Allowed to use the AKICK command"
rank = 250
level = 10
flag = "K"
}
/*
* ASSIGN privilege.
*
* Used by botserv/assign.
*
* Users with this permission can assign and unassign BotServ bots to and from the channel.
*/
privilege
{
name = "ASSIGN"
desc = "Allowed to assign/unassign a bot"
rank = 270
level = "founder"
flag = "s"
}
/*
* AUTOHALFOP privilege.
*
* Used by the core.
*
* Users with this permission get halfop on join.
*/
privilege
{
name = "AUTOHALFOP"
desc = "Automatic mode +h"
rank = 100
level = 4
flag = "H"
}
/*
* AUTOOP privilege.
*
* Used by the core.
*
* Users with this permission get op on join.
*/
privilege
{
name = "AUTOOP"
desc = "Automatic channel operator status"
rank = 210
level = 5
flag = "O"
}
/*
* AUTOOWNER privilege.
*
* Used by the core.
*
* Users with this permission get owner on join.
*/
privilege
{
name = "AUTOOWNER"
desc = "Automatic mode +q"
rank = 330
level = 9999
flag = "Q"
}
/*
* AUTOPROTECT privilege.
*
* Used by the core.
*
* Users with this permission get admin on join.
*/
privilege
{
name = "AUTOPROTECT"
desc = "Automatic mode +a"
rank = 240
level = 10
flag = "A"
}
/*
* AUTOVOICE privilege.
*
* Used by the core.
*
* Users with this permission get voice on join.
*/
privilege
{
name = "AUTOVOICE"
desc = "Automatic mode +v"
rank = 50
level = 3
flag = "V"
}
/*
* BADWORDS privilege.
*
* Used by botserv/badwords.
*
* Users with this permission can modify BotServ's BADWORDS list.
*/
privilege
{
name = "BADWORDS"
desc = "Allowed to modify channel badwords list"
rank = 260
level = 10
flag = "K"
}
/*
* BAN privilege.
*
* Used by chanserv/ban and chanserv/tban.
*
* Users with this permission can use the BAN command.
*/
privilege
{
name = "BAN"
desc = "Allowed to ban users"
rank = 150
level = 4
flag = "b"
}
/*
* FANTASIA privilege.
*
* Used by botserv/main and chanserv/xop.
*
* Users with this permission can use fantasy commands in the channel.
*/
privilege
{
name = "FANTASIA"
desc = "Allowed to use fantasy commands"
rank = 30
level = 3
flag = "c"
}
/*
* FOUNDER privilege.
*
* Used by botserv/info, chanserv/access, chanserv/akick,
* chanserv/clearusers, chanserv/drop, chanserv/set/founder,
* chanserv/set/securefounder, chanserv/set/successor and chanserv/xop.
*
* Users with this permission are treated as founders and can use
* commands restricted to founders.
*/
privilege
{
name = "FOUNDER"
desc = "Allowed to issue commands restricted to channel founders"
rank = 360
level = "founder"
flag = "F"
}
/*
* GETKEY privilege.
*
* Used by chanserv/getkey and nickserv/ajoin.
*
* Users with this permission can get they channel key with GETKEY and
* can use nickserv/ajoin to join channels with keys.
*/
privilege
{
name = "GETKEY"
desc = "Allowed to use GETKEY command"
rank = 180
level = 5
flag = "G"
}
/*
* GREET privilege.
*
* Used by botserv/main.
*
* Users with this permission get their greet shown on join.
*/
privilege
{
name = "GREET"
desc = "Greet message displayed on join"
rank = 40
level = 5
flag = "g"
}
/*
* HALFOP privilege.
*
* Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop.
*
* Users with this permission can use ChanServ to halfop and dehalfop
* others in the channel.
*/
privilege
{
name = "HALFOP"
desc = "Allowed to (de)halfop users"
rank = 120
level = 5
flag = "h"
}
/*
* HALFOPME privilege.
*
* Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop.
*
* Users with this permission can use ChanServ to halfop and dehalfop
* themselves in the channel.
*/
privilege
{
name = "HALFOPME"
desc = "Allowed to (de)halfop him/herself"
rank = 110
level = 4
flag = "h"
}
/*
* INFO privilege.
*
* Used by botserv/info and chanserv/info.
*
* Users with this permission are allowed to get the full INFO output
* from BotServ and ChanServ.
*/
privilege
{
name = "INFO"
desc = "Allowed to get full INFO output"
rank = 80
level = 9999
flag = "I"
}
/*
* INVITE privilege.
*
* Used by chanserv/invite and nickserv/ajoin.
*
* Users with this permission can invite users through ChanServ and
* join invite only channels with nickserv/ajoin.
*/
privilege
{
name = "INVITE"
desc = "Allowed to use the INVITE command"
rank = 190
level = 5
flag = "i"
}
/*
* KICK privilege.
*
* Used by chanserv/kick.
*
* Users with this permission can use the KICK command.
*/
privilege
{
name = "KICK"
desc = "Allowed to use the KICK command"
rank = 130
level = 4
flag = "k"
}
/*
* MEMO privilege.
*
* Used by memoserv/del, memoserv/ignore, memoserv/info, memoserv/list,
* memoserv/main, memoserv/read and memoserv/set.
*
* Users with this permission can manage channel memos.
*/
privilege
{
name = "MEMO"
desc = "Allowed to read channel memos"
rank = 280
level = 10
flag = "m"
}
/*
* MODE privilege.
*
* Used by chanserv/mode.
*
* Users with this permission can set modes through ChanServ and change
* the mode lock.
*/
privilege
{
name = "MODE"
desc = "Allowed to use the MODE command"
rank = 170
level = 5
flag = "s"
}
/*
* NOKICK privilege.
*
* Used by botserv/kick.
*
* Users with this permission are spared from automated BotServ kicks.
*/
privilege
{
name = "NOKICK"
desc = "Prevents users being kicked by Services"
rank = 20
level = 1
flag = "N"
}
/*
* OPDEOP privilege.
*
* Used by chanserv/mode, chanserv/op and chanserv/deop.
*
* Users with this permission can use ChanServ to op and deop
* others in the channel.
*/
privilege
{
name = "OPDEOP"
desc = "Allowed to (de)op users"
rank = 230
level = 5
flag = "o"
}
/*
* OPDEOPME privilege.
*
* Used by chanserv/mode, chanserv/op and chanserv/deop.
*
* Users with this permission can use ChanServ to op and deop
* themselves in the channel.
*/
privilege
{
name = "OPDEOPME"
desc = "Allowed to (de)op him/herself"
rank = 220
level = 5
flag = "o"
}
/*
* OWNER privilege.
*
* Used by chanserv/mode, chanserv/owner and chanserv/deowner.
*
* Users with this permission can use ChanServ to owner and deowner
* others in the channel.
*/
privilege
{
name = "OWNER"
desc = "Allowed to (de)owner users"
rank = 350
level = "founder"
flag = "q"
}
/*
* OWNERME privilege.
*
* Used by chanserv/mode, chanserv/owner and chanserv/deowner.
*
* Users with this permission can use ChanServ to owner and deowner
* themselves in the channel.
*/
privilege
{
name = "OWNERME"
desc = "Allowed to (de)owner him/herself"
rank = 340
level = "9999"
flag = "q"
}
/*
* PROTECT privilege.
*
* Used by chanserv/mode, chanserv/protect and chanserv/deprotect.
*
* Users with this permission can use ChanServ to protect and deprotect
* others in the channel.
*/
privilege
{
name = "PROTECT"
desc = "Allowed to (de)protect users"
rank = 310
level = 9999
flag = "a"
}
/*
* PROTECTME privilege.
*
* Used by chanserv/mode, chanserv/protect and chanserv/deprotect.
*
* Users with this permission can use ChanServ to protect and deprotect
* themselves in the channel.
*/
privilege
{
name = "PROTECTME"
desc = "Allowed to (de)protect him/herself"
rank = 300
level = 10
flag = "a"
}
/*
* SAY privilege.
*
* Used by botserv/control.
*
* Users with this permission can use the BotServ bot in the channel to
* say or do a /me with the provided message.
*/
privilege
{
name = "SAY"
desc = "Allowed to use SAY and ACT commands"
rank = 90
level = 5
flag = "B"
}
/*
* SET privilege.
*
* Used by botserv/kick, botserv/set, chanserv/clone, chanserv/log,
* chanserv/saset/noexpire and chanserv/set.
*
* Users with this permission can set what BotServ will kick for, change
* BotServ and ChanServ settings, clone ChanServ channel setings, and
* set ChanServ logging options.
*/
privilege
{
name = "SET"
desc = "Allowed to set channel settings"
rank = 320
level = 9999
flag = "s"
}
/*
* SIGNKICK privilege.
*
* Used by chanserv/ban and chanserv/kick.
*
* Users with this permission won't get their nick shown in the kick
* through ChanServ when the setting SIGNKICK is set to LEVEL.
*/
privilege
{
name = "SIGNKICK"
desc = "No signed kick when SIGNKICK LEVEL is used"
rank = 140
level = 9999
flag = "K"
}
/*
* TOPIC privilege.
*
* Used by chanserv/appendtopic and chanserv/topic.
*
* Users with this permission can change the channel topic through ChanServ.
*/
privilege
{
name = "TOPIC"
desc = "Allowed to change channel topics"
rank = 160
level = 5
flag = "t"
}
/*
* UNBAN privilege.
*
* Used by chanserv/unban.
*
* Users with this permission can unban themselves and others through ChanServ.
*/
privilege
{
name = "UNBAN"
desc = "Allowed to unban users"
rank = 200
level = 4
flag = "u"
}
/*
* VOICE privilege.
*
* Used by chanserv/mode, chanserv/voice and chanserv/devoice.
*
* Users with this permission can use ChanServ to voice and devoice
* others in the channel.
*/
privilege
{
name = "VOICE"
desc = "Allowed to (de)voice users"
rank = 70
level = 4
flag = "v"
}
/*
* VOICEME privilege.
*
* Used by chanserv/mode, chanserv/voice and chanserv/devoice.
*
* Users with this permission can use ChanServ to voice and devoice
* themselves in the channel.
*/
privilege
{
name = "VOICEME"
desc = "Allowed to (de)voice him/herself"
rank = 60
level = 3
flag = "v"
}
/*
@@ -314,6 +850,16 @@ module { name = "cs_ban" }
command { service = "ChanServ"; name = "BAN"; command = "chanserv/ban"; }
command { service = "ChanServ"; name = "KB"; command = "chanserv/ban"; }
/*
* cs_tban
*
* Provides the command chanserv/tban.
*
* Used for banning users from channels for a specified time.
*/
module { name = "cs_tban" }
command { service = "ChanServ"; name = "TBAN"; command = "chanserv/tban"; }
/*
* cs_clearusers
*
@@ -431,6 +977,16 @@ command { service = "ChanServ"; name = "K"; command = "chanserv/kick"; }
module { name = "cs_list" }
command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; permission = "chanserv/list"; }
/*
* cs_log
*
* Provides the command chanserv/log.
*
* Use for configuring what actions on channels are logged and where.
*/
module { name = "cs_log" }
command { service = "ChanServ"; name = "LOG"; command = "chanserv/log"; }
/*
* cs_mode
*
@@ -562,17 +1118,6 @@ module { name = "cs_set_misc" }
command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; }
command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; }
/*
* cs_set_opnotice
*
* Provides the commands chanserv/set/opnotice and chanserv/saset/opnotice.
*
* Used for setting whether channel ops should be notified of mode changes made through ChanServ.
*/
module { name = "cs_set_opnotice" }
command { service = "ChanServ"; name = "SET OPNOTICE"; command = "chanserv/set/opnotice"; }
command { service = "ChanServ"; name = "SASET OPNOTICE"; command = "chanserv/saset/opnotice"; permission = "chanserv/saset/opnotice"; }
/*
* cs_set_peace
*
@@ -735,6 +1280,17 @@ command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; }
module { name = "cs_unban" }
command { service = "ChanServ"; name = "UNBAN"; command = "chanserv/unban"; }
/*
* cs_updown
*
* Provides the commands chanserv/up and chanserv/down.
*
* Used for setting or removing your status modes on a channel.
*/
module { name = "cs_updown" }
command { service = "ChanServ"; name = "DOWN"; command = "chanserv/down"; }
command { service = "ChanServ"; name = "UP"; command = "chanserv/up"; }
/*
* cs_xop
*
+180 -44
View File
@@ -116,7 +116,7 @@ include
include
{
type = "executable"
name = "/usr/bin/wget -q -O - http://some.miconfigured.network.com/services.conf"
name = "/usr/bin/wget -q -O - http://some.misconfigured.network.com/services.conf"
}
*/
@@ -192,7 +192,7 @@ serverinfo
* the Operating System choose the local address. This directive is optional.
*
* If you don't know what this means or don't need to use it, just leave this
* directives commented out.
* directive commented out.
*/
#localhost = "nowhere."
@@ -358,7 +358,7 @@ options
expiretimeout = 30m
/*
* Sets the timout period for reading from the uplink.
* Sets the timeout period for reading from the uplink.
*/
readtimeout = 5s
@@ -370,7 +370,7 @@ options
/*
* Sets the (maximum) frequency at which the timeout list is checked. This,
* combined with readtimeout above, determine how accurately timed events,
* combined with readtimeout above, determines how accurately timed events,
* such as nick kills, occur; it also determines how much CPU time Services
* will use doing this. Higher values will cause less accurate timing but
* less CPU usage.
@@ -504,10 +504,15 @@ options
retrywait = 60
/*
* If set, Services will hide commands that users doesn't have the privileges to execute
* If set, Services will hide commands that users don't have the privileges to execute
* from HELP output.
*/
hideprivilegedcommands = no
/*
* If set, Services do not allow ownership of nick names, only ownership of accounts.
*/
nonicknameownership = no
}
/*
@@ -539,7 +544,7 @@ include
/*
* [RECOMMENDED] Global
*
* Includes global.example.conf, which is necessary for Global funcionality.
* Includes global.example.conf, which is necessary for Global functionality.
*
* Remove this block to disable Global.
*/
@@ -552,7 +557,7 @@ include
/*
* [OPTIONAL] HostServ
*
* Includes hostserv.example.conf, which is necessary for HostServ funcionality.
* Includes hostserv.example.conf, which is necessary for HostServ functionality.
*
* Remove this block to disable HostServ.
*/
@@ -565,7 +570,7 @@ include
/*
* [OPTIONAL] MemoServ
*
* Includes memoserv.example.conf, which is necessary for MemoServ funcionality.
* Includes memoserv.example.conf, which is necessary for MemoServ functionality.
*
* Remove this block to disable MemoServ.
*/
@@ -578,7 +583,7 @@ include
/*
* [OPTIONAL] NickServ
*
* Includes memoserv.example.conf, which is necessary for NickServ funcionality.
* Includes memoserv.example.conf, which is necessary for NickServ functionality.
*
* Remove this block to disable NickServ.
*/
@@ -591,7 +596,7 @@ include
/*
* [RECOMMENDED] OperServ
*
* Includes operserv.example.conf, which is necessary for OperServ funcionality.
* Includes operserv.example.conf, which is necessary for OperServ functionality.
*
* Remove this block to disable OperServ.
*/
@@ -617,7 +622,13 @@ log
* - globops
*/
target = "services.log"
/* Log to both services.log and the channel #services */
/* Log to both services.log and the channel #services
*
* Note that some older IRCds, such as Ratbox, require services to be in the
* log channel to be able to message it. To do this, configure service:channels to
* join your logging channel.
*/
#target = "services.log #services"
/*
@@ -634,12 +645,6 @@ log
*/
logage = 7
/*
* Enable to have the core services clients join and stay in the log channel(s) when logging.
* Note: on some IRCds this is not optional, and is enforced on.
*/
inhabitlogchannel = yes
/*
* What types of log messages should be logged by this block. There are nine general categories:
*
@@ -703,7 +708,7 @@ log
* This block is recommended, as without it you will be unable to access most oper commands.
* It replaces the old ServicesRoot directive amongst others.
*
* The command names below are defaults and are configured in commands.conf. If you configure
* The command names below are defaults and are configured in the *serv.conf's. If you configure
* additional commands with permissions, such as commands from third party modules, the permissions
* must be included in the opertype block before the command can be used.
*
@@ -712,10 +717,11 @@ log
* chanserv/access/modify - Can modify channel access and akick lists
* chanserv/auspex - Can see any information with /chanserv info
* chanserv/no-register-limit - May register an unlimited number of channels and nicknames
* chanserv/set - Can modify the settings of any channel (incl. changing of the owner and password!)
* chanserv/set - Can modify the settings of any channel (incl. changing of the owner!)
* 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
* memoserv/no-limit - Can send memos through limits and throttles
* nickserv/access - Can modify other users access list
* nickserv/auspex - Can see any information with /nickserv info
* nickserv/confirm - Can confirm other users nicknames
* nickserv/drop - Can drop other users nicks
@@ -724,11 +730,11 @@ log
* 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/getkey chanserv/mode
* chanserv/list chanserv/suspend chanserv/topic chanserv/status
* chanserv/access/list chanserv/drop chanserv/getkey chanserv/invite
* chanserv/list chanserv/suspend chanserv/topic chanserv/clearusers
*
* chanserv/saset/bantype chanserv/saset/description chanserv/saset/email chanserv/saset/entrymsg
* chanserv/saset/founder chanserv/saset/keeptopic chanserv/saset/opnotice chanserv/saset/restricted
* chanserv/saset/bantype chanserv/saset/description chanserv/saset/email
* chanserv/saset/founder chanserv/saset/keeptopic chanserv/saset/restricted
* chanserv/saset/peace chanserv/saset/persist chanserv/saset/private
* chanserv/saset/secure chanserv/saset/securefounder chanserv/saset/secureops
* chanserv/saset/signkick chanserv/saset/successor chanserv/saset/topiclock
@@ -782,7 +788,7 @@ opertype
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/modlist operserv/sqline operserv/oper operserv/kick operserv/ignore operserv/snline"
commands = "chanserv/list chanserv/suspend chanserv/topic memoserv/staff nickserv/sendpass nickserv/resetpass nickserv/suspend operserv/mode operserv/chankill operserv/szline operserv/akill operserv/session operserv/modlist operserv/sqline operserv/oper operserv/kick operserv/ignore operserv/snline"
/* What privs (see above) this opertype has */
privs = "chanserv/auspex chanserv/no-register-limit memoserv/* nickserv/auspex nickserv/confirm"
@@ -836,11 +842,24 @@ oper
/* The opertype this person will have */
type = "Services Root"
/* If set, the user must be an oper on the IRCd to gain their Services
* oper privileges.
*/
require_oper = yes
/* An optional password. If defined the user must login using /operserv login first */
#password = "secret"
/* An optional SSL fingerprint. If defined is required to use this opertype. */
#certfp = "ed3383b3f7d74e89433ddaa4a6e5b2d7"
/* An optional list of user@host masks. If defined the user must be connected from one of them */
#host = "*@*.anope.org ident@*"
/* An optional vhost to set on users who identify for this oper block.
* This will override HostServ vhosts, and may not be available on all IRCds
*/
#vhost = "oper.mynet"
}
/*
@@ -863,6 +882,10 @@ oper
* This section contains settings related to the use of e-mail from Services.
* If the usemail directive is set to yes, unless specified otherwise, all other
* directives are required.
*
* NOTE: Users can find the IP of the machine services is running on by examining
* mail headers. If you do not want your IP known, you should set up a mail relay
* to strip the relevant headers.
*/
mail
{
@@ -924,6 +947,68 @@ mail
* if you are using ESMTP or QMail to send out e-mails.
*/
#dontquoteaddresses = yes
/*
* The subject and message of emails sent to users when they register accounts.
*/
registration_subject = "Nickname Registration for %n"
registration_message = "Hi,
You have requested to register the nickname %n on %N.
Please type \" /msg NickServ confirm %c \" to complete registration.
If you don't know why this mail was sent to you, please ignore it silently.
%N administrators."
/*
* The subject and message of emails sent to users when they request a new password.
*/
reset_subject = "Reset password request for %n"
reset_message = "Hi,
You have requested to have the password for %n reset.
To reset your password, type \" /msg NickServ CONFIRM %n %c \"
If you don't know why this mail was sent to you, please ignore it silently.
%N administrators."
/*
* The subject and message of emails sent to users when they request SENDPASS.
*/
sendpass_subject = "Nickname password for %n"
sendpass_message = "Hi,
You have requested to receive the password of nickname %n by e-mail.
The password is %p. 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.
%N administrators."
/*
* The subject and message of emails sent to users when they request a new email address.
*/
emailchange_subject = "Email confirmation"
emailchange_message = "Hi,
You have requested to change your email address to %e.
Please type \" /msg NickServ confirm %c \" to confirm this change.
If you don't know why this mail was sent to you, please ignore it silently.
%N administrators."
/*
* The subject and message of emails sent to users when they recieve a new memo.
*/
memo_subject = "New memo"
memo_message = "Hi %n
You've just received a new memo from %s. This is memo number %d.
Memo text:
%t"
}
/*
@@ -958,11 +1043,32 @@ dns
*/
/*
* db_plain
* [DEPRECATED] db_old
*
* This is the default flatfile database format.
* This is the old binary database format from late Anope 1.7.x, Anope 1.8.x, and
* early Anope 1.9.x. This module only loads these databases, and will NOT save them.
* You should only use this to upgrade old databases to a newer database format by loading
* other database modules in addition to this one, which will be used when saving databases.
*/
module { name = "db_plain" }
#module { name = "db_old" }
db_old
{
/*
* This is the encryption type used by the databases. This must be set correctly or
* your passwords will not work. Valid options are: md5, oldmd5, sha1, and plain.
*/
#hash = "md5"
}
/*
* [DEPRECATED] db_plain
*
* This is the flatfile database format from Anope-1.9.2 to Anope-1.9.5.
* To convert from this format, load both this and db_flatfile. Be sure to name db_flatfile's
* target database to something else. Start Anope then shut down so the new database will be written.
* Then unload this and restart Anope, loading from the new database.
*/
#module { name = "db_plain" }
db_plain
{
/*
@@ -972,25 +1078,55 @@ db_plain
}
/*
* db_mysql and db_mysql_live
* db_flatfile
*
* Enables (live) MySQL support.
*
* The db_mysql_live module is an extension to db_mysql, and should only be used if
* db_mysql is being used. This module pulls data in real time from SQL as it is
* requested by the core as a result of someone executing commands.
*
* This effectively allows you to edit your database and have it be immediately
* reflected back in Anope.
*
* At this time db_mysql_live only supports pulling data in real time from the three
* main tables: anope_cs_info, anope_ns_alias, and anope_ns_core.
*
* db_mysql provides the command operserv/sqlsync, which is used for importing other database
* methods into MySQL.
* This is the default flatfile database format.
*/
#module { name = "db_mysql" }
#module { name = "db_mysql_live" }
module { name = "db_flatfile" }
db_flatfile
{
/*
* The database name db_flatfile should use
*/
database = "anope.db"
}
/*
* db_sql
*
* This module allows saving and loading databases using one of the SQL engines.
*
* WARNING: This module will delete every table in the database it uses. Be sure
* to put Anope in its own separate database.
*/
#module { name = "db_sql" }
db_sql
{
/*
* The SQL service db_sql should use, these are configured in modules.conf.
* For MySQL, this should probably be mysql/main.
*/
engine = "sqlite/main"
}
/*
* db_sql_live_read, db_sql_live_write
*
* Enables (live) SQL support.
*
* The db_sql_live modules are an extension to db_sql, and should only be used if
* db_sql is being used.
*
* The db_sql_live_read module pulls data in real time from
* SQL as it is needed by the core.
* At this time this supports the three main tables: ChannelInfo, NickAlias, and NickCore.
*
* The db_sql_live_write module writes data to SQL in real time as it is modified by
* the core.
*
*/
#module { name = "db_sql_live_read" }
#module { name = "db_sql_live_write" }
/*
* [REQUIRED] Encryption modules.
+10 -1
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for Global.
*/
module { name = "gl_main" }
module { name = "global" }
/*
* Configuration for Global provided by gl_main.
+38 -1
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for HostServ.
*/
module { name = "hs_main" }
module { name = "hostserv" }
/*
* Configuration for HostServ provided by hs_main.
@@ -57,6 +66,34 @@ hostserv
* The name of the client that should be HostServ.
*/
name = "HostServ"
/*
* The characters allowed in a vhost. Changing this is not recommended unless
* you know for sure your IRCd supports whatever characters you are wanting to use.
* Telling services to set a vhost containing characters your IRCd disallows could
* potentially break the IRCd and/or Services. Note these are 1 byte characters, so
* UTF-8 characters will not work.
*
* It is recommended you DON'T change this.
*/
vhost_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
/*
* If set, allows vhosts to not contain dots (.).
* Newer IRCds generally do not have a problem with this, but the same warning as
* vhost_chars applies.
*
* It is recommended you DON'T change this.
*/
allow_undotted_vhosts = false
/*
* The characters that are not allowed to be at the very beginning or very ending
* of a vhost. The same warning as vhost_chars applies.
*
* It is recommended you DON'T change this.
*/
disallow_start_or_end = ".-"
}
/*
+11 -2
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for MemoServ.
*/
module { name = "ms_main" }
module { name = "memoserv" }
/*
* Configuration for MemoServ provided by ms_main.
@@ -197,7 +206,7 @@ module { name = "ms_send" }
command { service = "MemoServ"; name = "SEND"; command = "memoserv/send"; }
/*
* ms_sendlal
* ms_sendall
*
* Provides the command memoserv/sendall
*
+123 -3
View File
@@ -197,13 +197,13 @@ m_ldap_oper
/*
* m_mysql
*
* This module allows other modules (db_mysql/db_mysql_live) to use MySQL.
* Be sure you have imported the table schema with mydbgen before
* trying to use MySQL
* This module allows other modules to use MySQL.
*/
#module { name = "m_mysql" }
mysql
{
/* The name of this service */
name = "mysql/main"
database = "anope"
server = "127.0.0.1"
username = "anope"
@@ -211,6 +211,126 @@ mysql
port = 3306
}
/*
* m_proxyscan
*
* This module allows you to scan connecting clients for open proxies.
* Note that using this will allow users to get the IP or your services.
*
* Currently the two supported proxy types are HTTP and SOCKS5.
*
* The proxy scanner works by attempting to connect to clients when they
* connect to the network, and if they have a proxy running instruct it to connect
* back to services. If services are able to connect through the proxy to itself
* then it knows it is an insecure proxy, and will ban it.
*/
#module { name = "m_proxyscan" }
m_proxyscan
{
/*
* The target IP services tells the proxy to connect back to. This must be a publicly
* avaiable IP that remote proxies can connect to.
*/
#target_ip = "127.0.0.1"
/*
* The port services tells the proxy to connect to.
*/
target_port = 7226
/*
* The listen IP services listen on for incoming connections from suspected proxies.
* This probably will be the same as target_ip, but may not be if you are behind a firewall (NAT).
*/
#listen_ip = "127.0.0.1"
/*
* The port services should listen on for incoming connections from suspected proxies.
* This most likely will be the same as target_port.
*/
listen_port = 7226
/*
* An optional notice sent to clients upon connect.
*/
#connect_notice = "We will now scan your host for insecure proxies. If you do not consent to this scan please disconnect immediately"
/*
* Who the notice should be sent from.
*/
#connect_source = "OperServ"
/*
* If set, OperServ will add infected clients to the akill list. Without it, OperServ simply sends
* a timed G/K-line to the IRCd and forgets about it. Can be useful if your akill list is being fill up by bots.
*/
add_to_akill = yes
/*
* How long before connections should be timed out.
*/
timeout = 5
}
/*
* A proxyscan block (must have m_proxyscan loaded).
* You may have multiple proxyscan blocks.
*/
proxyscan
{
/* The type of proxy to check for. A comma separated list is allowed */
type = "HTTP"
/* The ports to check */
port = "80,8080"
/* How long to set the ban for */
time = 4h
/*
* The reason to ban the user for.
* %h is replaced with the type of proxy found.
* %i is replaced with the IP of proxy found.
* %p is replaced with the port.
*/
reason = "You have an open proxy running on your host (%t:%i:%p)"
}
/*
* m_sqlite
*
* This module allows other modules to use SQLite.
*/
#module { name = "m_sqlite" }
sqlite
{
/* The name of this service */
name = "sqlite/main"
/* The database name, it will be created if it does not exist. */
database = "anope.db"
}
/*
* m_rewrite
*
* Allows rewriting commands sent to clients.
*/
#module { name = "m_rewrite" }
rewrite
{
/* The client to apply this rewrite to. */
client = "ChanServ"
/* Source message to match. A $ can be used to match anything. */
source_message = "CLEAR $ USERS"
/*
* Message to rewrite the source message to. A $ followed by a number, eg $0, gets
* replaced by the number-th word from the source_message, starting from 0.
*/
target_message = "CLEARUSERS $1"
}
/*
* m_ssl
*
+37 -19
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for NickServ.
*/
module { name = "ns_main" }
module { name = "nickserv" }
/*
* Configuration for NickServ provided by ns_main.
@@ -202,7 +211,7 @@ nickserv
guestnickprefix = "Guest"
/*
* Prevents the use of the DROP, FORBID, GETPASS, and SET PASSWORD commands by Services Admins
* Prevents the use of the ACCESS, DROP, FORBID, GETPASS, and SET PASSWORD commands by Services Admins
* on other Services Admins or the Services Root(s).
*
* This directive is optional, but recommended.
@@ -247,7 +256,7 @@ nickserv
*
* Additionally, you may provide a permission name that must be in the opertype of users executing the command.
*
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
* Sane defaults are provided below that do not need to be edited unless you wish to change the default behaviour.
*/
/* Give it a help command */
@@ -433,25 +442,33 @@ command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpas
/*
* ns_saset
*
* Provides commands nickserv/saset, nickserv/saset/display, and nickserv/saset/password.
* Provides commands nickserv/saset, nickserv/saset/password.
*
* Used as a help wrapper for SASET commands, and used to force change users display name or password.
* Used as a help wrapper for SASET commands, and used to force change users password.
*/
module { name = "ns_saset" }
command { service = "NickServ"; name = "SASET"; command = "nickserv/saset"; }
command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/saset/display"; }
command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; }
/*
* ns_saset_noexpire
*
* Provides the command nickserv/saset/noexpire.
*
* Used for configuring noexpire, which prevents nicks from expiring.
*/
module { name = "ns_saset_noexpire" }
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire" }
/*
* ns_set
*
* Provides the commands nickserv/set, nickserv/set/display, and nickserv/set/password.
* Provides the commands nickserv/set, nickserv/set/password.
*
* Used as a help wrapper for SET commands, and used for users to change their display name or password.
* Used as a help wrapper for SET commands, and used for users to change their password.
*/
module { name = "ns_set" }
command { service = "NickServ"; name = "SET"; command = "nickserv/set"; }
command { service = "NickServ"; name = "SET DISPLAY"; command = "nickserv/set/display"; }
command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
/*
@@ -465,6 +482,17 @@ module { name = "ns_set_autoop" }
command { service = "NickServ"; name = "SET AUTOOP"; command = "nickserv/set/autoop"; }
command { service = "NickServ"; name = "SASET AUTOOP"; command = "nickserv/saset/autoop"; permission = "nickserv/saset/autoop"; }
/*
* ns_set_display
*
* Provides the commands nickserv/set/display and nickserv/saset/display.
*
* Used for setting users display names.
*/
module { name = "ns_set_display" }
command { service = "NickServ"; name = "SET DISPLAY"; command = "nickserv/set/display"; }
command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/saset/display"; permission = "nickserv/saset/display"; }
/*
* ns_set_email
*
@@ -553,16 +581,6 @@ module { name = "ns_set_secure" }
command { service = "NickServ"; name = "SET SECURE"; command = "nickserv/set/secure"; }
command { service = "NickServ"; name = "SASET SECURE"; command = "nickserv/saset/secure"; permission = "nickserv/saset/secure"; }
/*
* ns_saset_noexpire
*
* Provides the command nickserv/saset/noexpire.
*
* Used for configuring noexpire, which prevents nicks from expiring.
*/
module { name = "ns_saset_noexpire" }
command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire" }
/*
* ns_sendpass
*
+24 -11
View File
@@ -39,6 +39,15 @@ service
* unable to do certain things if this option is enabled.
*/
#modes = "+o"
/*
* An optional comma separated list of channels this service should join. Outside
* of log channels this is not very useful, as the service will just idle in the
* specified channels, and will not accept any types of commands.
*
* Prefixes may be given to the channels in the form of mode character or prefix symbol.
*/
#channels = "@#services,#mychan"
}
/*
@@ -46,7 +55,7 @@ service
*
* Provides essential functionality for OperServ.
*/
module { name = "os_main" }
module { name = "operserv" }
/*
* Configuration for OperServ provided by os_main.
@@ -68,7 +77,7 @@ operserv
/*
* These define the default expiration times for, respectively, AKILLs, CHANKILLs, SNLINEs,
* SQLINEs, and SZLINEs.
* and SQLINEs.
*/
autokillexpiry = 30d
chankillexpiry = 30d
@@ -110,7 +119,6 @@ operserv
* - akillexpire: An AKILL has expired
* - snlineexpire: An SNLINE has expired
* - sqlineexpire: An SQLINE has expired
* - szlineexpire: An SZLINE has expired
* - exceptionexpire: A session exception has expired
*
* This directive is optional, if left blank, there will be no notifications.
@@ -125,8 +133,7 @@ operserv
* should be noted that session limiting, along with a large exception list, can degrade Services'
* performance.
*
* See the source and comments in sessions.c and the online help for more information about
* session limiting.
* See the online help for more information about session limiting.
*
* This directive is optional.
*/
@@ -198,6 +205,12 @@ operserv
*/
addakiller = yes
/*
* Adds akill IDs to akills. Akill IDs are given to users in their ban reason and can be used to easily view,
* modify, or remove an akill from the ID.
*/
akillids = yes
/*
* If set, only IRC Operators will be permitted to use OperServ, regardless of module-based command
* access restrictions.
@@ -236,7 +249,7 @@ command { service = "OperServ"; name = "AKILL"; command = "operserv/akill"; perm
*
* Provides the command operserv/chankill.
*
* Used to akill uses from an entire channel.
* Used to akill users from an entire channel.
*/
module { name = "os_chankill" }
command { service = "OperServ"; name = "CHANKILL"; command = "operserv/chankill"; permission = "operserv/chankill"; }
@@ -422,12 +435,13 @@ command { service = "OperServ"; name = "KILL"; command = "operserv/kill"; permis
/*
* os_login
*
* Provides the command operserv/login.
* Provides the commands operserv/login and operserv/logout.
*
* Used to login to OperServ, only required if your oper block requires this.
*/
module { name = "os_login" }
command { service = "OperServ"; name = "LOGIN"; command = "operserv/login"; }
command { service = "OperServ"; name = "LOGOUT"; command = "operserv/logout"; }
/*
* os_mode
@@ -499,7 +513,7 @@ command { service = "OperServ"; name = "OLINE"; command = "operserv/oline"; perm
/*
* os_oper
*
* Provides the command opersev/oper.
* Provides the command operserv/oper.
*
* Used to configure opers and show information about opertypes.
*/
@@ -532,7 +546,7 @@ command { service = "OperServ"; name = "SESSION"; command = "operserv/session";
*
* Provides the command operserv/set.
*
* Used to set various settinsg such as superadmin, debug mode, etc.
* Used to set various settings such as superadmin, debug mode, etc.
*/
module { name = "os_set" }
command { service = "OperServ"; name = "SET"; command = "operserv/set"; permission = "operserv/set"; }
@@ -572,14 +586,13 @@ command { service = "OperServ"; name = "SVSNICK"; command = "operserv/svsnick";
/*
* os_sxline
*
* Provides the operserv/snline, operserv/sqline, and operserv/szline commands.
* Provides the operserv/snline and operserv/sqline commands.
*
* Used to ban different things such as realnames, nicknames, and IPs.
*/
module { name = "os_sxline" }
command { service = "OperServ"; name = "SNLINE"; command = "operserv/snline"; permission = "operserv/snline"; }
command { service = "OperServ"; name = "SQLINE"; command = "operserv/sqline"; permission = "operserv/sqline"; }
command { service = "OperServ"; name = "SZLINE"; command = "operserv/szline"; permission = "operserv/szline"; }
/*
* os_update
-426
View File
@@ -1,426 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 3.3.5
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Aug 07, 2011 at 03:53 PM
-- Server version: 5.1.50
-- PHP Version: 5.3.6-pl0-gentoo
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Database: `anope`
--
-- --------------------------------------------------------
--
-- Table structure for table `anope_bs_badwords`
--
CREATE TABLE IF NOT EXISTS `anope_bs_badwords` (
`channel` varchar(255) NOT NULL DEFAULT '',
`word` varchar(255) NOT NULL,
`type` varchar(50) NOT NULL,
UNIQUE KEY `channel` (`channel`,`word`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_bs_core`
--
CREATE TABLE IF NOT EXISTS `anope_bs_core` (
`nick` varchar(255) NOT NULL DEFAULT '',
`user` varchar(255) NOT NULL DEFAULT '',
`host` text NOT NULL,
`rname` text NOT NULL,
`flags` text NOT NULL,
`created` int(10) unsigned NOT NULL DEFAULT '0',
`chancount` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`nick`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_bs_info_metadata`
--
CREATE TABLE IF NOT EXISTS `anope_bs_info_metadata` (
`botname` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`value` text NOT NULL,
KEY `FK_anope_bs_info_metadata_botname` (`botname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_access`
--
CREATE TABLE IF NOT EXISTS `anope_cs_access` (
`provider` varchar(255) NOT NULL DEFAULT '',
`data` varchar(255) NOT NULL DEFAULT '',
`mask` varchar(255) NOT NULL DEFAULT '',
`channel` varchar(255) NOT NULL DEFAULT '',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`creator` varchar(255) NOT NULL DEFAULT '',
`created` int(11) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`mask`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_akick`
--
CREATE TABLE IF NOT EXISTS `anope_cs_akick` (
`channel` varchar(255) NOT NULL DEFAULT '',
`flags` varchar(255) NOT NULL DEFAULT '',
`mask` varchar(255) NOT NULL DEFAULT '',
`reason` text NOT NULL,
`creator` varchar(255) NOT NULL DEFAULT '',
`created` int(10) unsigned NOT NULL DEFAULT '0',
`last_used` int(10) unsigned NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`mask`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_info`
--
CREATE TABLE IF NOT EXISTS `anope_cs_info` (
`name` varchar(255) NOT NULL DEFAULT '',
`founder` text NOT NULL,
`successor` text NOT NULL,
`descr` text NOT NULL,
`time_registered` int(10) unsigned NOT NULL DEFAULT '0',
`last_used` int(10) unsigned NOT NULL DEFAULT '0',
`last_topic` text NOT NULL,
`last_topic_setter` text NOT NULL,
`last_topic_time` int(10) unsigned NOT NULL DEFAULT '0',
`flags` text NOT NULL,
`bantype` smallint(6) NOT NULL DEFAULT '0',
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
`botnick` varchar(255) NOT NULL DEFAULT '',
`botflags` text NOT NULL,
`capsmin` smallint(6) NOT NULL DEFAULT '0',
`capspercent` smallint(6) NOT NULL DEFAULT '0',
`floodlines` smallint(6) NOT NULL DEFAULT '0',
`floodsecs` smallint(6) NOT NULL DEFAULT '0',
`repeattimes` smallint(6) NOT NULL DEFAULT '0',
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_info_metadata`
--
CREATE TABLE IF NOT EXISTS `anope_cs_info_metadata` (
`channel` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`value` text NOT NULL,
KEY `FK_anope_cs_info_metadata_channel` (`channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_levels`
--
CREATE TABLE IF NOT EXISTS `anope_cs_levels` (
`channel` varchar(255) NOT NULL DEFAULT '',
`position` int(11) NOT NULL DEFAULT '0',
`level` int(11) NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`position`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_mlock`
--
CREATE TABLE IF NOT EXISTS `anope_cs_mlock` (
`channel` varchar(255) NOT NULL,
`mode` varchar(127) NOT NULL,
`status` int(11) NOT NULL,
`setter` varchar(255) NOT NULL,
`created` int(11) NOT NULL,
`param` varchar(255) NOT NULL,
UNIQUE KEY `entry` (`channel`,`mode`,`status`,`setter`,`param`),
KEY `FK_anope_cs_mlock` (`channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_cs_ttb`
--
CREATE TABLE IF NOT EXISTS `anope_cs_ttb` (
`channel` varchar(255) NOT NULL DEFAULT '',
`ttb_id` int(11) NOT NULL DEFAULT '0',
`value` int(11) NOT NULL DEFAULT '0',
UNIQUE KEY `channel` (`channel`,`ttb_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_extra`
--
CREATE TABLE IF NOT EXISTS `anope_extra` (
`data` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_hs_core`
--
CREATE TABLE IF NOT EXISTS `anope_hs_core` (
`nick` varchar(255) NOT NULL,
`vident` varchar(64) NOT NULL,
`vhost` varchar(255) NOT NULL,
`creator` varchar(255) NOT NULL,
`time` int(11) NOT NULL,
KEY `FK_anope_hs_core_nick` (`nick`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_info`
--
CREATE TABLE IF NOT EXISTS `anope_info` (
`version` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ms_info`
--
CREATE TABLE IF NOT EXISTS `anope_ms_info` (
`receiver` varchar(255) NOT NULL,
`flags` int(11) NOT NULL DEFAULT '0',
`time` int(10) unsigned NOT NULL DEFAULT '0',
`sender` text NOT NULL,
`text` blob NOT NULL,
`serv` enum('NICK','CHAN') NOT NULL DEFAULT 'NICK',
KEY `FK_anope_ms_info_receiver` (`receiver`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_access`
--
CREATE TABLE IF NOT EXISTS `anope_ns_access` (
`display` varchar(255) NOT NULL DEFAULT '',
`access` varchar(160) NOT NULL,
KEY `FK_anope_ns_access_display` (`display`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_alias`
--
CREATE TABLE IF NOT EXISTS `anope_ns_alias` (
`nick` varchar(255) NOT NULL DEFAULT '',
`last_quit` text NOT NULL,
`last_realname` text NOT NULL,
`last_usermask` text NOT NULL,
`last_realhost` text NOT NULL,
`time_registered` int(10) unsigned NOT NULL DEFAULT '0',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`flags` text NOT NULL,
`display` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`nick`),
KEY `FK_anope_ns_alias_display` (`display`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_alias_metadata`
--
CREATE TABLE IF NOT EXISTS `anope_ns_alias_metadata` (
`nick` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`value` text NOT NULL,
KEY `FK_anope_ns_alias_metadata_nick` (`nick`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_core`
--
CREATE TABLE IF NOT EXISTS `anope_ns_core` (
`display` varchar(255) NOT NULL DEFAULT '',
`pass` text NOT NULL,
`email` text NOT NULL,
`greet` text NOT NULL,
`flags` text NOT NULL,
`language` varchar(5) NOT NULL DEFAULT '',
`memomax` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`display`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_ns_core_metadata`
--
CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` (
`nick` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`value` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_core`
--
CREATE TABLE IF NOT EXISTS `anope_os_core` (
`maxusercnt` int(11) NOT NULL DEFAULT '0',
`maxusertime` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_exceptions`
--
CREATE TABLE IF NOT EXISTS `anope_os_exceptions` (
`mask` varchar(255) NOT NULL,
`slimit` int(11) NOT NULL DEFAULT '0',
`who` text NOT NULL,
`reason` text NOT NULL,
`time` int(10) unsigned NOT NULL DEFAULT '0',
`expires` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `anope_os_xlines`
--
CREATE TABLE IF NOT EXISTS `anope_os_xlines` (
`type` varchar(1) NOT NULL,
`mask` varchar(255) NOT NULL,
`xby` text NOT NULL,
`reason` text NOT NULL,
`seton` int(10) unsigned NOT NULL DEFAULT '0',
`expire` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `anope_bs_badwords`
--
ALTER TABLE `anope_bs_badwords`
ADD CONSTRAINT `FK_anope_bs_badwords_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_bs_info_metadata`
--
ALTER TABLE `anope_bs_info_metadata`
ADD CONSTRAINT `FK_anope_bs_info_metadata_botname` FOREIGN KEY (`botname`) REFERENCES `anope_bs_core` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_access`
--
ALTER TABLE `anope_cs_access`
ADD CONSTRAINT `FK_anope_cs_access_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_akick`
--
ALTER TABLE `anope_cs_akick`
ADD CONSTRAINT `FK_anope_cs_akick_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_info_metadata`
--
ALTER TABLE `anope_cs_info_metadata`
ADD CONSTRAINT `FK_anope_cs_info_metadata_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_levels`
--
ALTER TABLE `anope_cs_levels`
ADD CONSTRAINT `FK_anope_cs_levels_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_mlock`
--
ALTER TABLE `anope_cs_mlock`
ADD CONSTRAINT `FK_anope_cs_mlock_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_cs_ttb`
--
ALTER TABLE `anope_cs_ttb`
ADD CONSTRAINT `FK_anope_cs_ttb_channel` FOREIGN KEY (`channel`) REFERENCES `anope_cs_info` (`name`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_hs_core`
--
ALTER TABLE `anope_hs_core`
ADD CONSTRAINT `FK_anope_hs_core_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ms_info`
--
ALTER TABLE `anope_ms_info`
ADD CONSTRAINT `FK_anope_ms_info_receiver` FOREIGN KEY (`receiver`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_access`
--
ALTER TABLE `anope_ns_access`
ADD CONSTRAINT `FK_anope_ns_access_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_alias`
--
ALTER TABLE `anope_ns_alias`
ADD CONSTRAINT `FK_anope_ns_alias_display` FOREIGN KEY (`display`) REFERENCES `anope_ns_core` (`display`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `anope_ns_alias_metadata`
--
ALTER TABLE `anope_ns_alias_metadata`
ADD CONSTRAINT `FK_anope_ns_alias_metadata_nick` FOREIGN KEY (`nick`) REFERENCES `anope_ns_alias` (`nick`) ON DELETE CASCADE ON UPDATE CASCADE;
+166 -1
View File
@@ -1,3 +1,168 @@
Revision 378ae4c - Fri, 3 Feb 2012 15:18:06 -0500 - Regenerate language files
Revision ce2a0f7 - Tue, 31 Jan 2012 16:19:47 -0500 - Fixed a memory leak in m_ldap
Revision be5ba49 - Tue, 31 Jan 2012 15:44:04 -0500 - Not sure what I was thinking here
Revision b4f27da - Tue, 31 Jan 2012 15:35:51 -0500 - Bug #1365 - Fixed nickserv/confirm syntax for services opers
Revision d09a302 - Thu, 26 Jan 2012 17:04:59 -0500 - Also refuse to load memoserv modules if memoserv isn't loaded
Revision 0f90927 - Wed, 25 Jan 2012 16:13:38 -0500 - Added two common warning messages on Windows to ignore
Revision 52eaa7d - Wed, 25 Jan 2012 15:48:07 -0500 - Windows
Revision e88e37c - Tue, 24 Jan 2012 18:28:37 -0500 - Add some checks in ms_* to make sure memoserv really exists
Revision f10f49d - Tue, 24 Jan 2012 16:42:21 -0500 - Added missing expires column in /os akill view
Revision d06cdaa - Tue, 24 Jan 2012 16:35:54 -0500 - Fixed os_ignore to check against users real IPs, not to match against opers, and check for expired ignores on /os ignore list
Revision fc20bd7 - Tue, 24 Jan 2012 16:03:44 -0500 - Add tracking for Unreal's usermode +I
Revision b3d9412 - Sun, 22 Jan 2012 17:49:23 +0100 - added a french INSTALL file, thanks to MacLeod for translating
Revision 98feb1b - Sat, 21 Jan 2012 00:50:48 -0500 - Cleaned up bs_kick and fixed amsg kicker
Revision 94c302b - Fri, 20 Jan 2012 20:50:36 +0000 - Fixed param check from last commit
Revision cdb6bb8 - Fri, 20 Jan 2012 17:50:09 +0000 - Updated DEFCON and fixed Defcons disabling of the removed mlock command
Revision a851f84 - Fri, 20 Jan 2012 15:03:49 +0000 - Corrected some incorrect English
Revision a270a13 - Sun, 15 Jan 2012 02:59:09 -0500 - Fixed crash from last commit
Revision 964d63c - Sun, 15 Jan 2012 01:47:31 -0500 - Improve on db_sql_live_read
Revision f38faed - Sat, 14 Jan 2012 15:58:51 +0000 - Fixed an incorrect crash-causing response when an invalid option is specified in botservs kickers
Revision c462a69 - Fri, 13 Jan 2012 15:37:17 -0500 - Only match users nicks against access list entries if the entry is a mask... accidentally removed from an earlier fix for #1368
Revision 14a2c9c - Wed, 11 Jan 2012 19:04:40 -0500 - Fixed loading db_sql_live_read's configuration values on startup
Revision a52ed70 - Tue, 10 Jan 2012 17:58:56 -0500 - Don't ever attempt to process CTCPs as regular messages
Revision 7c03e60 - Tue, 10 Jan 2012 17:53:48 -0500 - Removed this "valid" ip check in cidr::cidr, is wrong for IPv6 and ::pton checks this anyway using inet_pton. Also fixed a comment Robby broke in chanserv.conf
Revision 1e9d88a - Tue, 10 Jan 2012 17:06:08 -0500 - Add support for Unreals extban ~a:
Revision 815e140 - Sun, 8 Jan 2012 19:42:48 -0500 - Fixed loading akill reasons
Revision f824557 - Sun, 8 Jan 2012 18:14:07 -0500 - Fixed topic lock on inspircd
Revision 830c5ca - Sat, 7 Jan 2012 16:21:31 -0500 - Cleanup of cs_tban
Revision 9e71394 - Sat, 7 Jan 2012 04:10:30 -0500 - Cleaned up a lot of log messages, help replies, fixed cs_tban, and other small fixes
Revision dd64eac - Sat, 7 Jan 2012 03:44:43 -0500 - Fixed users not being able to delete their own access with /cs access when using numbers, and clean up cs_xop slightly
Revision 4204ece - Mon, 2 Jan 2012 21:28:24 -0500 - Updated Copyright to 2012
Revision 60a5cc1 - Sat, 31 Dec 2011 03:04:44 -0500 - Bug #1369 - Fixed os_svsnick to allow changing the case of a users' nick
Revision 20aa4e8 - Sat, 31 Dec 2011 01:33:32 -0500 - Bug #1368 - check all members of a users gruop against the access list
Revision f1b05ac - Wed, 28 Dec 2011 12:49:04 -0500 - Fixed this back now unreal sends 0 for non logged in users
Revision a4bf770 - Wed, 28 Dec 2011 04:31:44 -0500 - Added ESVID support to unreal32 Also fixes a crash due to unreal's ESVID change when users connect.
Revision 150831c - Tue, 27 Dec 2011 23:11:14 -0500 - Made capab management a bit simplier
Revision 1a4157b - Fri, 23 Dec 2011 12:29:30 -0500 - Add DT_ALLOW_EMPTY config flag, allow fantasychars to be empty
Revision 3bcb285 - Thu, 22 Dec 2011 03:46:35 -0500 - Somehow these two modules got mixed up..
Revision 704dbe2 - Tue, 20 Dec 2011 18:38:37 -0500 - Updated /bs info output and note db_sql can truncate entire databases
Revision bbddf50 - Mon, 19 Dec 2011 17:13:38 -0500 - Fixed botserv kickers
Revision e5851ad - Mon, 19 Dec 2011 16:07:28 -0500 - Fixed saving databases with MySQL when shut down by SIGINT
Revision 03119f2 - Mon, 19 Dec 2011 15:41:14 -0500 - Made m_dnsbl ban IPs not hostnames
Revision 45fc3ce - Mon, 19 Dec 2011 15:37:15 -0500 - Fixed formatting of many lists and INFO outputs
Revision d320c73 - Sat, 17 Dec 2011 10:30:13 +0000 - Fixed entry messages not displaying.
Revision ca8ce89 - Sat, 17 Dec 2011 02:06:53 +0000 - Fixed a slight error in email registration/resend and some minor typos.
Revision c88a751 - Thu, 15 Dec 2011 02:29:13 -0500 - Add privilege ranks to determine how powerful privileges are
Revision 9ea030d - Thu, 15 Dec 2011 01:14:13 -0500 - Fixed access comparators
Revision ad14c81 - Mon, 12 Dec 2011 15:37:08 -0500 - Update channel last used times when founders use the channel, too
Revision 255a8da - Mon, 12 Dec 2011 15:26:59 -0500 - Added oper:require_oper configuration option
Revision 4211dcf - Sun, 11 Dec 2011 17:03:33 -0500 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 3c5337f - Sun, 11 Dec 2011 17:01:56 -0500 - Fixed translating messages with varargs sent directly to users, too
Revision d2f788c - Sun, 11 Dec 2011 05:17:19 +0000 - Added K to vhost_chars...
Revision fa54d5a - Thu, 8 Dec 2011 17:29:17 -0500 - Fixed a memory leak in m_sqlite
Revision aeefe16 - Mon, 5 Dec 2011 11:52:40 -0500 - Bug #1364 - fixed crash in /cs kick
Revision c80e784 - Sat, 3 Dec 2011 19:17:41 -0500 - Attempt to fix issue with modules having their link libraries in the wrong order.
Revision 620c08b - Fri, 25 Nov 2011 23:12:23 +0000 - Fixed some more errors in sql live-write, hopefully the last.
Revision 23a9270 - Fri, 25 Nov 2011 23:10:26 +0000 - Fixed a crash in ns saset when using mysql-write module
Revision cef3eb7 - Fri, 25 Nov 2011 00:44:31 -0500 - Remove send_cmd and replace it with a stringstream
Revision 12d0a73 - Mon, 21 Nov 2011 16:24:45 -0500 - Merge branch '1.9' of ssh://anope.git.sf.net/gitroot/anope/anope into 1.9
Revision 0dd85f7 - Mon, 21 Nov 2011 16:17:17 -0500 - Fixed not translating messages using varargs
Revision 51d6e8e - Sun, 20 Nov 2011 18:41:46 -0500 - CMake handles strings and lists differently, so this should hopefully finally fix the linking issue.
Revision 3f14882 - Sun, 20 Nov 2011 18:34:13 -0500 - Apparently pstdint.h was NOT included way back with commit 377a7a9 to use something similar to stdint.h
Revision 5a17b06 - Sun, 20 Nov 2011 18:32:47 -0500 - Really fix linking in libraries (even if gettext isn't found on *nix), and a minor nitpick about the leading spaces on LINK_LIBS.
Revision bf8e4ac - Sun, 20 Nov 2011 16:09:59 -0500 - Attempt to fix where link libraries are set when compiling to fix failed builds on systems that require -ldl.
Revision 781ed11 - Sun, 20 Nov 2011 15:31:01 -0500 - Allow services operators to modify other users access list
Revision 6f8f749 - Fri, 18 Nov 2011 16:20:17 -0500 - Allow kicking and banning by mask
Revision c43cdf4 - Fri, 18 Nov 2011 11:22:01 -0500 - Added operserv/logout
Revision 8374211 - Fri, 18 Nov 2011 00:36:54 -0500 - Allow having multiple fantasy characters
Revision 69dfc72 - Thu, 17 Nov 2011 12:46:18 -0500 - Fixed storing mode locks
Revision 5281282 - Wed, 16 Nov 2011 16:22:58 -0500 - Fixed compile error
Revision 503eb42 - Tue, 15 Nov 2011 16:30:31 -0500 - Made looking up a level for a nonexistant privilege debugg log a warning, not abort
Revision 38d90c7 - Tue, 15 Nov 2011 16:27:32 -0500 - Fixed loading ssl certs for users
Revision 1356498 - Tue, 15 Nov 2011 16:22:02 -0500 - Prevent locking mode Z on unrealircd
Revision 9ed203c - Tue, 15 Nov 2011 16:16:38 -0500 - Fixed crash on shutdown & a compiler warning
Revision b5ff856 - Tue, 8 Nov 2011 17:29:16 -0500 - Windows
Revision 97b9055 - Sat, 5 Nov 2011 15:05:15 -0400 - Remove xlines from the IRCd aswell as from our list when the clear command is used, and fixed adding timed Zlines to inspircd
Revision 5f0b933 - Sat, 5 Nov 2011 00:11:49 -0400 - Set proper expirys on ZLines if the IRCd supports it
Revision b3194a1 - Fri, 4 Nov 2011 19:39:27 -0400 - Updated Changes
Revision d01f4ea - Fri, 4 Nov 2011 18:04:12 -0400 - Allow /os userlist to match host and ip too
Revision a42cafb - Fri, 4 Nov 2011 17:55:14 -0400 - Store flags for memos, fixed the expiring very soon message, fixed /os session view when a session exception is added at a lower limit than th default
Revision 066e5b3 - Fri, 4 Nov 2011 02:28:21 -0400 - Delete all tables before flushing not just ones we know about
Revision 09dba47 - Thu, 3 Nov 2011 18:59:51 -0400 - Added an assignment operator for Serializable because some STL containers use it which causes iterators to become invalidated
Revision ca33ac6 - Thu, 3 Nov 2011 02:28:29 -0400 - Bug #1354 - Allow mode chars to be used for channel prefixs in services.conf
Revision 302989b - Tue, 1 Nov 2011 01:11:26 -0400 - Clarify the message when users try to lock modes they don't have access to lock
Revision 22b7d9f - Tue, 1 Nov 2011 00:15:28 -0400 - Added a copy constructor to dynamic_reference to allow references to reference other references correctly
Revision 9dd71c4 - Sat, 29 Oct 2011 21:16:50 -0400 - Fixed the signal/fork/wait mess hopefully once and for all. fork() did not copy kqueue descriptors on freebsd which caused problems
Revision 655c1cc - Thu, 27 Oct 2011 18:21:49 -0400 - Fix a few warnings that only showed up with gcc 3.4.6 here (sadly, there is one on every file about anonymous variadic macros that I can't get rid of).
Revision d9333e0 - Thu, 27 Oct 2011 18:01:56 -0400 - Clear flags before rebuilding them from the databases. Fixes bug #1351 where default flags would always be set when unserializing objects.
Revision 39ac438 - Thu, 27 Oct 2011 15:09:31 -0400 - Ignore sigchld/usr2 sent to the child process after fork
Revision 0761a4a - Thu, 27 Oct 2011 14:46:20 -0400 - Bug #1350 + other related fixes
Revision 66ca256 - Thu, 27 Oct 2011 13:50:32 -0400 - Fixed loading exceptions in db_plain
Revision 961bb6e - Thu, 27 Oct 2011 00:13:00 +0100 - Fixed some typos/errors in the example configs comments.
Revision b14f5ea - Wed, 26 Oct 2011 16:52:00 -0400 - Fixed accidentally clearing botmodes when joins are sent
Revision bf66336 - Wed, 26 Oct 2011 15:29:45 -0400 - Bug #1347, fixed incorrect param parsing in cs_set_misc
Revision c79a575 - Wed, 26 Oct 2011 15:17:05 -0400 - Bug #1348 - Fixed /cs entrymsg list
Revision 8334128 - Wed, 26 Oct 2011 14:31:58 -0400 - Removed the old unordered_map code
Revision 7c62de1 - Mon, 24 Oct 2011 16:37:29 -0400 - Merge branch '1.9' of anope.git.sf.net:/gitroot/anope/anope into 1.9
Revision 377a7a9 - Mon, 24 Oct 2011 16:32:29 -0400 - Fixed bug #1349 (m_sqlite compiles without error under FreeBSD), as well as use C99's stdint.h (or cstdint if available) to get (u)intX_t types instead of our stupid typedefs. pstdint.h included in case there is no cstdint or stdint.h available.
Revision ccf29c0 - Mon, 24 Oct 2011 13:19:51 -0400 - Fixed the capab parser to parse capab tokens prefixed with :. Fixes not detecting quitstorm support on ratbox
Revision d0513d6 - Sat, 22 Oct 2011 16:11:26 -0400 - A few minor fixups
Revision f4a0bdd - Sat, 22 Oct 2011 12:45:55 -0400 - Added our own eventfd test for openvz machines which have eventfd but can not be used
Revision 3e2ac36 - Sat, 22 Oct 2011 11:35:31 -0400 - Bug #1343 - don't allow recovering and ghosting enforcers
Revision c8b3809 - Sat, 22 Oct 2011 11:21:21 -0400 - Added akill ids
Revision ad2ef75 - Sat, 22 Oct 2011 11:20:50 -0400 - Fixed a race condition with installing signal handlers and forking
Revision 6ce9010 - Fri, 21 Oct 2011 18:01:51 -0400 - Fixed extracting multiple words from our serializable stringstream
Revision d0afc8c - Fri, 21 Oct 2011 00:21:34 -0400 - Added m_rewrite
Revision 230b3bc - Thu, 20 Oct 2011 13:38:37 -0400 - Only fork if we are at term
Revision 1cfb630 - Thu, 20 Oct 2011 11:54:56 -0400 - Fixed a crash in clearusers
Revision d16f962 - Wed, 19 Oct 2011 12:59:16 -0400 - Bug #1342 - fixed tracking chmodes in bahamuts sjoin
Revision fc16746 - Tue, 18 Oct 2011 12:18:18 -0400 - Prevent chankill from akilling my clients
Revision eb5b5f9 - Tue, 18 Oct 2011 12:06:51 -0400 - Fixed compile errors on release build
Revision faea452 - Tue, 18 Oct 2011 01:48:05 -0400 - Reorder some stuff in Init & the ts6 proto mods to fix weirdness from bots being introduced by 3rd party modules
Revision 2c614d5 - Sat, 15 Oct 2011 02:08:52 -0400 - Fixed up anoperc to work with the newer startup method
Revision 89b4be6 - Sat, 15 Oct 2011 00:54:32 -0400 - Fixed crash on /os oper del
Revision 28ca0e1 - Fri, 14 Oct 2011 22:07:13 -0400 - Fork earlier in startup to prevent it messing up threads, if there are any
Revision 2504af7 - Fri, 14 Oct 2011 12:53:28 -0400 - Fixed os_forbid adds reason if no expiry is given
Revision ddc3c2f - Fri, 14 Oct 2011 12:20:07 -0400 - Added options:nonicknameownership config option
Revision 53275c3 - Tue, 11 Oct 2011 02:50:37 -0400 - Don't add new levels to existing channels default, screws with stuff when the config is reloaded
Revision f3f6727 - Tue, 11 Oct 2011 00:09:26 -0400 - Bug #1337
Revision 4681e3a - Mon, 10 Oct 2011 17:19:06 -0400 - Allow chanserv/suspend to take an expiry time
Revision 80f4f31 - Mon, 10 Oct 2011 15:04:23 -0400 - Put serialized_items on the heap to prevent weird crashes on shutdown from the list being destructed before members in it
Revision 9f3d735 - Mon, 10 Oct 2011 14:16:59 -0400 - Allow nickserv/suspend to take an expiry time
Revision 0e012f7 - Sun, 9 Oct 2011 21:29:34 -0400 - Check for being at terminal before forking
Revision 9f85033 - Sun, 9 Oct 2011 02:52:13 -0400 - Give more verbose messages on startup
Revision af273e3 - Sun, 25 Sep 2011 15:34:56 -0400 - Store flags for objects, also fixes bug #1333
Revision 1f3e96f - Sun, 25 Sep 2011 14:42:09 -0400 - Made channel privileges case insensitive
Revision e7ba639 - Sun, 25 Sep 2011 14:38:21 -0400 - Remove opnotice from example configs
Revision 1f2399d - Sun, 25 Sep 2011 04:19:15 -0400 - Added a new database format and sqlite support. Also moved db-convert to a module.
Revision 43201ea - Mon, 19 Sep 2011 18:35:40 -0400 - Fixed /os reload doing weird things to service channels, and allow setting modes by clients on burst
Revision 7dce64e - Mon, 19 Sep 2011 13:14:20 -0400 - Fixed missing _ in cs_appendtopic
Revision 1184eb5 - Mon, 19 Sep 2011 13:12:52 -0400 - Allow OnPreHelp to stop processing
Revision 4c2a492 - Mon, 19 Sep 2011 12:36:52 -0400 - Call fantasy events even if the commands for them don't exist
Revision be77a7e - Mon, 19 Sep 2011 12:29:54 -0400 - Bug #1334 - fixed crash on /os oper info
Revision 934723f - Mon, 19 Sep 2011 12:14:02 -0400 - LOG_COMMAND must now always give a valid command
Revision f07295c - Fri, 16 Sep 2011 14:07:33 -0400 - Bug #1332 - Fixed ValidateUser to not require secure off to disable nickserv kill
Revision 26c1d67 - Sat, 10 Sep 2011 16:27:10 -0400 - Fixed compile errors & warnings from 1.9.6 to 1.9 merge
Revision 3d5889c - Sat, 10 Sep 2011 16:08:58 -0400 - Updated channel flag names to remove LOGCHAN
Revision 213c1c4 - Sat, 10 Sep 2011 02:42:18 -0400 - Changed msgmerge to not use -E.. it will escape all of some languages and mess up poedit etc. Keep it in xgettext for the bold/underline characters.
Revision 63cb8ca - Sat, 10 Sep 2011 02:06:31 -0400 - Moved signal/thread/mode checking to use signal pipes
Revision dc5d1fa - Sat, 10 Sep 2011 02:06:31 -0400 - Made ChanServ privileges configurable
Revision 563d158 - Sat, 10 Sep 2011 02:06:31 -0400 - Allow Config to install cmake
Revision 1478b5b - Sat, 10 Sep 2011 02:06:29 -0400 - Added chanserv/log
Revision 19e0b87 - Sat, 10 Sep 2011 02:05:56 -0400 - Removed /bs set msg
Revision 17ea4ed - Sat, 10 Sep 2011 02:05:03 -0400 - Fixed service_reference to work correctly with external classes
Revision feaef7c - Sat, 10 Sep 2011 02:05:03 -0400 - Allow services to register or unregister themselves
Revision c6d3fbd - Sat, 10 Sep 2011 02:05:02 -0400 - Added kqueue
Revision 700a585 - Sat, 10 Sep 2011 02:05:00 -0400 - Allow modules to add their own channel levels
Revision 62752db - Sat, 10 Sep 2011 01:58:39 -0400 - Rewrote mlock saving/loading code to not use this silly extensible hack
Revision f025d1b - Sat, 10 Sep 2011 01:58:38 -0400 - Made service_reference type safe
Revision 8c4417c - Sat, 10 Sep 2011 01:58:38 -0400 - Removed opnotice
Revision d4db2b8 - Sat, 10 Sep 2011 01:58:38 -0400 - Made the IsValidHost checks configurable
Revision bb8e04c - Sat, 10 Sep 2011 01:58:35 -0400 - Added oper:host and oper:vhost
Revision b504791 - Sat, 10 Sep 2011 01:55:37 -0400 - Cleaned up the dns engine, and fixed sometimes parsing multiple answer queries incorrectly
Revision d5749c1 - Sat, 10 Sep 2011 01:55:37 -0400 - Fixed eventfd pipeengine to not add the same socket twice
Revision f54ab5e - Sat, 10 Sep 2011 01:55:29 -0400 - Squash merge of 1.9 to 1.9.6
Revision 1e45019 - Sat, 10 Sep 2011 01:55:11 -0400 - Added m_proxyscan
Revision 2eb708e - Sat, 10 Sep 2011 01:55:09 -0400 - Cleaned up some of the socket code, cleaned up the pipe engines, added support for binary sockets, and cleaned up the asynch connect/accept code
Revision 4fcb371 - Sat, 10 Sep 2011 01:52:59 -0400 - Track what "level" channel status modes are, which allows us to have chanserv/mode determine if a status mode can be set by users better
Revision 6401d93 - Sat, 10 Sep 2011 01:52:59 -0400 - Added chanserv/up and chanserv/down
Revision 8a9a39c - Sat, 10 Sep 2011 01:52:59 -0400 - Renamed the core pseudoclient modules to match their names
Revision 13e8b26 - Sat, 10 Sep 2011 01:52:59 -0400 - Made email messages sent by services configurable
Revision 8a6d657 - Sat, 10 Sep 2011 01:52:46 -0400 - Removed log:inhabitlogchannel and replaced it with service:channels
Revision 4a7ba7e - Sat, 10 Sep 2011 00:58:35 -0400 - Removed SZLine. Instead, have AKILL determine whether or not a ZLINE should be set.
Revision 2b5d9f3 - Sat, 10 Sep 2011 00:54:29 -0400 - Bump for 1.9.6 git
Revision 3a502f2 - Fri, 9 Sep 2011 23:28:58 -0400 - Anope 1.9.5 Release
Revision b6dad37 - Fri, 9 Sep 2011 23:28:37 -0400 - Update version.log
Revision 3cbad7f - Fri, 9 Sep 2011 23:27:15 -0400 - Regenerate language files
Revision b80a0a8 - Fri, 9 Sep 2011 22:27:51 -0400 - Updated Greek language file
Revision f844b0a - Fri, 9 Sep 2011 19:18:43 -0400 - Changed User::IsRecognized check to default to secure
@@ -782,7 +947,7 @@ Revision 0d2d7e9 - Sun, 20 Jun 2010 20:05:23 -0400 - Fixed Windows build
Revision 63d7bee - Sun, 20 Jun 2010 18:51:03 -0400 - Merge branch '1.9' of ssh://anope.git.sf.net/gitroot/anope/anope into 1.9
Revision 381c9c8 - Sun, 20 Jun 2010 18:42:58 -0400 - The first of a few "CBX OCDing over code style" commits, focusing on include/* and src/* but not src/core/* or src/modules/*.
Revision e8a1570 - Sun, 20 Jun 2010 14:04:17 -0400 - Added m_helpchan to replace the cores helpchannel functionality
Revision 968e4d0 - Sun, 20 Jun 2010 13:11:31 -0400 - Fixed the name of cs_forbid in chanserv:modules so it really loads
Revision 968e4d0b - Sun, 20 Jun 2010 13:11:31 -0400 - Fixed the name of cs_forbid in chanserv:modules so it really loads
Revision 7b7e2a6 - Sat, 19 Jun 2010 21:22:48 -0400 - Updated TODO
Revision 448eadd - Sat, 19 Jun 2010 20:53:53 -0400 - Made db-converter add all of the core clients when converting a 1.8 database
Revision 68b54f3 - Sat, 19 Jun 2010 13:39:12 -0400 - Made db-converter only write mlock params if there really is one, fixes some problems with converting mlock for certain databases
+19
View File
@@ -1,3 +1,22 @@
Anope Version 1.9.6
--------------------
A Added ability to configure emails sent by services
A Added chanserv/up and chanserv/down
A Added m_proxyscan
A Added more configurability for what vhosts are valid
A Added chanserv/log
A Added ability to configure ChanServ privileges
A Added a new database format
A Added SQLite support
A Added more verbose messages on startup
A Added ability for chanserv/suspend and nickserv/suspend to take an expiry time
A Added no nickname ownership config option
A Added m_rewrite
A Added akill IDs
F Fixed crash in clearusers
F Fixed crash in /os oper info
F Fixed eventfd Config check to work properly on OpenVZ
Anope Version 1.9.5
--------------------
A Extended LDAP support
+10
View File
@@ -1,3 +1,13 @@
Anope Version 1.9.6
-------------------
service:channels added to join services to channels
mail block modified to allow configuring of email messages
oper:host and oper:vhost added
oper:require_oper added
options:nonicknameownership added
operserv:akillids added
nickserv/access oper privilege added
Anope Version 1.9.5
-------------------
Don't even try it, get a new config and start over.
+9 -12
View File
@@ -31,10 +31,11 @@ Anope DefCon
The DefCon system is part of Anope's core,
The DefCon system has to be configured on your services.conf file to
be enabled. The defcon module will not unload unless all non-optional
directives are set. Look for the defcon block
section on your services.conf file for more information.
The DefCon system has to be configured on your operserv.conf file to
be enabled. Defcon will be disabled if "defaultlevel" in the defcon
block is left commented, or set to 0. Look for the defcon block
on your operserv.conf file for more information on enabling and
configuring it.
Make sure you restart Anope after changing the DefCon configuration
directives.
@@ -45,7 +46,7 @@ Anope DefCon
No new channel registrations
No New Nick Registrations
No MLOCK changes
No Mode Lock changes
Force Chan Mode
Use Reduced Session Limit
KILL any new clients trying to connect
@@ -55,7 +56,7 @@ Anope DefCon
No new memos sent to block MemoServ attacks
Information regarding how to enable this for specific defcon levels can
be found in services.conf
be found in operserv.conf
4) Usage
@@ -70,22 +71,18 @@ Anope DefCon
/msg OperServ DEFCON 4
*** Global -- from OperServ: dengel Changed the DEFCON level to 4
-OperServ- Services are now at DEFCON 4
-OperServ- * No new channel registrations
-OperServ- * No new nick registrations
-OperServ- * No MLOCK changes
-OperServ- * No mode lock changes
-OperServ- * Use the reduced session limit of 5
-Global- The Defcon Level is now at Level: 4
-Global- The Defcon Level is now at: 4
Restore normal readiness:
/msg OperServ DEFCON 5
*** Global -- from OperServ: dengel Changed the DEFCON level to 5
-OperServ- Services are now at DEFCON 5
-Global- Services are now back to normal, sorry for any inconvenience
+209
View File
@@ -0,0 +1,209 @@
Installation et instructions d'anope
------------------------------------
1) Instalation d'anope
2) Mise à jour d'anope
3) Configuration de l'ircd
4) Mise en route de anope
5) Mise en place d'un fichier crontab
Note: Vous devrez également lire les fichiers README et FAQ !
1) Installation de anope
Note importante: il n'est pas recommandé d'utiliser (et même d'installer)
Anope en tant que root.
Utilisez un utilisateur non privilégié,
La première chose que vous devez faire est d'obtenir le package Anope (si ce n'est déjà fait).
Vous pouvez le trouver ici http://www.anope.org/
Anope peut être installer de deux façons.
1. La méthode recommandée est d'utiliser CMake.
Vous pouvez vérifier si CMake est déjà installé sur votre système en utilisant la
commande: cmake --version ( sur votre vps ou dedier etre loggué en root )
Si c'est installé, vous aurez une ligne qui dit quelque chose qui ressemble à
«version 2.6 cmake-patch 1".
Si la version est inférieure à 2,4 ou si vous obtenez une erreur disant que la commande n'a pas été trouvé,
vous ne serez pas en mesure d'utiliser CMake,
sauf si vous installez vous-même dans votre répertoire home. CMake
vous pouvez le téléchargé ici > http://www.cmake.org/cmake/resources/software.html
Si vous n'arrivez pas à installer (soit en raison du manque d'espace
ou de restrictions par votre fournisseur d'hébergement),
vous pouvez encore utiliser le script de configuration fournis.
Cette option n'est pas recommandée et finira par être retiré, mais il est fourni pour la compatibilité de ces
manque de CMake.
Ensuite, décompressez le package dans votre répertoire home, et allez dans le répértoire
qui viens d'être crée.
Maintenant, tapez ./Config pour lancer le script de configuration. Il va vous poser
quelques questions, et compiler Anope sur votre système.
Si vous ne savez pas repondre à une question, utilisez la valeur par défaut.
Vous pouvez maintenant taper make pour compiler Anope. S'il ya des erreurs dans la
Makefile, * essayez d'utiliser * gmake au lieu. Si cela ne fonctionne toujours pas, vous (ou
votre fournisseur ) doit installer GNU make. Vous pouvez
le Trouvez sur ftp://prep.ai.mit.edu/pub/gnu/.
Maintenant, tapez make install (ou gmake install; voir ci-dessus). Cela permet d'installer
tous les fichiers nécessaires dans les chemins que vous avez spécifié dans la configuration
script, et les permissions du fichier de configuration. Vous devez vous assurer que les données
répertoire ne sont pas accessible par d'autres utilisateurs, que des utilisateurs malveillants peuvent
causer des problèmes sur votre réseau, si les mots de passe ne sont pas cryptés, ou de lire
les mémos de tout utilisateur.
Si vous voyez des erreurs lors de ce processus, s'il vous plaît nous envoyer un mail avec le * complet *
sortie d'erreur, et n'oubliez pas de mentionner votre OS, compilateur et bibliothèque C + +
versions.
Maintenant, allez dans le répertoire de données (par défaut, cd ~/services/data). ouvrer exemple.conf
avec votre éditeur de texte favori. Il contient toute la configuration
directives. Anope va l'utiliser au démarrage. Lisez attentivement les instructions contenues dans
le fichier. l'utilisation des valeurs par defauld n'est pas recomment et anope ne risque pas de fonctionner
Si vous avez besoin d'aide, vous devez vous abonner à la mailing list et par courrier Anope
pour se faire aider par d'autres utilisateurs. Voir le fichier README pour plus de
informations.
2) Mise à jour Anope
Si vous avez un fichier .Diff et que vous voulez patcher les ancienne sources Anope avec,
effectuer les opérations suivantes:
* Copiez le fichier .Diff dans le répertoire racine des sources Anope.
* Type de patch-p1 <file.diff
Notez que la mise à jour anope avec un fichier patch n'est pas recommandé.
Vous devez télécharger une nouvelle source propre, car cela vous donnera les meilleurs résultats..
Pour mettre à jour Anope, suivez simplement les instructions d'installation décrites dans
l'article 1. Il y a cependant quelques règles spécifiques:
* IMPORTANT: Sauvegardez vos anciennes bases de données!
* Si vous mettez à jour vers une nouvelle version majeure, toujours redémarrer avec un
fichier de configuration neuve example.conf.
3) Mise en place du IRCd
Ce Services agit comme un serveur IRC avec des pseudo-clients sur elle. Pour les relier à
votre réseau, vous aurez besoin d'ajouter quelques lignes dans le ircd.conf de leur plate-forme
serveur (comme indiqué dans la directive de configuration RemoteServer).
Pour les échantillons ci-dessous, nous allons prendre services.localhost.net que le nom de la
Services (comme indiqué dans la directive de configuration ServerName). Notez que
présente des échantillons sont faites pour être aussi générique que possible, mais il pourrait y avoir
de petites variations, en fonction de votre IRCd. Pour IRCd aide spécifique aux
de configuration, lire près de la fin de cette section.
Tout d'abord, les lignes C / N, qui permettent aux services de crée un lien. Ils ont également besoin d'un
Y: ligne fonctionne correctement.
Y: 27:180:0:0:4000000
C: 127.0.0.1: mypass: services.localhost.net: 30
N: 127.0.0.1: mypass: services.localhost.net: 30
"mot de pass" est le même mot de passe que vous avez mentionné dans le RemoteServer
directive de configuration. 127.0.0.1 est l'adresse IP à partir de laquelle les services se connecterons
à partir de (reliant en localhost est le moyen le plus efficace pour exécuter les services).
Ensuite, vous avez à mettre en place un U:ligne, qui permettra aux services de changer
modes de canal, de sujets, et bien plus encore, sans être op sur le canal.
U: services.localhost.net: *: *
REMARQUE: si vous avez plus d'un serveur dans votre réseau, cette ligne doit
être ajouté sur tous les autres serveurs, où cela ne risque pas de fonctionner correctement.
Enfin, vous aurez besoin d'ajouter un H:ligne, pour permttre la commande OperServ JUPE
de fonctionner correctement.
H:*::Services.LocalHost.Net
Ne pas oublier de /rehash votre IRCd pour appliquer les modifications.
Une nouvelle tendance dans la configuration ircd hybride, Unreal et Bahamut, qui utilisent une approche plus
«Lisibles» sous forme de configuration. Pour ceux, utiliser quelque chose comme:
link services.localhost.net
{
username *;
hostname localhost;
bind-ip *;
port 6667;
hub *;
password-connect "mypass";
password-receive "mypass";
class servers;
};
Notez que ce bloc de fichiers de configuration de style est diffèrent
sur le IRCd. Consultez le fabricant de lien interactif (le lien est ci-dessous) pour plus
détails sur la configuration exacte utilisée par votre IRCd.
Si vous êtes incapable d'obtenir un lien avec votre IRCd après la lecture de cet article,
vous pouvez essayer le fabricant lien interactif, qui est situé au:
http://anope.org/ilm.php
4) A partir Anope
Allez dans le répertoire où les fichiers binaires ont été installés (par défaut, ce n'est
~/ Services/ bin). Tapez. /Services à lancer Anope.
S'il ya des erreurs de syntaxe dans le fichier de configuration, ils seront
affiche sur l'écran. Corrigez-les jusqu'à ce qu'il n'y à plus d'erreur.
Un démarrage réussi ne générera pas de message.
Donner aux services au moins une minute pour se connecté à votre réseau, comme certains
IRCds sur certains OS peut être très lent pour le processus de liaison. Si rien n'arrive après environ une minute,
il y a probablement un problème de configuration. Essayez
de lancer Anope en mode debug ./services-debug-nofork pour voir toutes les erreurs qu'il
rencontres, et d'essayer de les corriger.
Si vous avez besoin d'aide pour résoudre des erreurs, n'hésitez pas à vous abonner à la Anope
liste de diffusion et de poser là. Voir le fichier README pour plus de détails.
5) Mettre en place un crontab
Une entrée crontab vous permettra de vérifier périodiquement que Anope est
toujours en cours, et redémarrez-le s'il n'est pas.
D'abord renommer le script example.chk qui est dans le chemin de Anope (par défaut,
cela est ~/services/data) pour services.chk et le modifier. Vous aurez besoin de
modifier la partie configuration du fichier. Assurez-vous ensuite que le fichier est
marqué comme exécutable en tapant chmod + x services.chk, et essayer de lancer le
script pour voir si cela fonctionne (Anope ne doit pas être en marche lorsque vous faites cela ;))
Lorsque cela est fait, vous devrez ajouter l'entrée crontab. Type de crontab-e.
Cela va ouvrir l'éditeur de texte par défaut avec le fichier crontab. Entrez le chemin
suivant (avec le chemin correct):
* / 5 * * * * /home/ircd/services/data/services.chk> /dev/nul 2> & 1
Le * / 5 au commencement signifie "vérifier toutes les 5 minutes". Vous pouvez remplacer
le 5 avec un autre numéro si vous voulez (mais moins de 60). Consulter
pages de manuel de votre système pour plus de détails sur la syntaxe de la crontab
fichier. Intéressant pages de manuel sont crontab (5), crontab (1) et cron (8).
Sauvegarder et quitter, et il est installé.
+1 -1
View File
@@ -1,7 +1,7 @@
Anope -- a set of IRC services for IRC networks
-----------------------------------------------
Anope is 2003-2011 Anope Team <team@anope.org>.
Anope is 2003-2012 Anope Team <team@anope.org>.
Based on Epona 2000-2002 PegSoft <epona@pegsoft.net>.
Based on Services 1996-1999 Andrew Church <achurch@achurch.org>.
-11
View File
@@ -3,17 +3,6 @@ Legend:
? = unsure
+ = in progress
1.9.5
-----
[+] More LDAP
[x] Rewrite silly forbid system
[x] Fix the modules language system to work without needing its own functions..
[x] Rewrite commands system
[x] Rewrite access system
[x] NS INFO: separate field for last seen realhost, shown to SRA only
[x] Configurable bot usermodes
Future
------
[ ] NS IDENTIFY changes
+2 -22
View File
@@ -26,36 +26,16 @@ Anope for Windows
(NOTE: When installing, tell CMake to add itself to the PATH.)
If you have Visual C++ 10 (2010) skip ahead to step 2, else you
need to download the following free components from Microsoft. Once
need to download the following free component from Microsoft. Once
downloaded, install these packages.
* Microsoft Visual C++ 2010 Express Edition:
http://www.microsoft.com/express/vc/
or
then download and install:
* Microsoft Windows 2008 SDK:
http://www.microsoft.com/downloads/details.aspx?FamilyId=E6E1C3DF-A74F-4207-8586-711EBE331CDC&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
Custom option, and only select to have the Developer Tools installed, but also expand that and deselect
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.)
2) Unpack the Anope tarball with your favorite uncompression program
(WinZip or WinRAR, etc).
3) (Note before this step: If you fall under one of the situations at the end of Step 1 where it says that the
SDK will not work out of the box, do not bring up the Visual C++ Command Prompt by using the link in
the Windows Start Menu. Instead, edit vsvars32.bat in the directory where you unpacked the source code
in step 2, so the first line that says "@SET VSINSTALLDIR=<whatever>" has the directory where you installed
Visual C++ Express to, if different from the default. Save the file and then run it instead.)
Bring up the Visual C++ Command Prompt; This will launch a
3) Bring up the Visual C++ Command Prompt; This will launch a
DOS Command Prompt like window, which will set the environment
properties needed to make Anope.
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
/* XMLRPC Functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
*/
+37 -46
View File
@@ -1,45 +1,31 @@
#ifndef ACCESS_H
#define ACCESS_H
enum ChannelAccess
enum
{
CA_ACCESS_LIST,
CA_NOKICK,
CA_FANTASIA,
CA_GREET,
CA_AUTOVOICE,
CA_VOICEME,
CA_VOICE,
CA_INFO,
CA_SAY,
CA_AUTOHALFOP,
CA_HALFOPME,
CA_HALFOP,
CA_KICK,
CA_SIGNKICK,
CA_BAN,
CA_TOPIC,
CA_MODE,
CA_GETKEY,
CA_INVITE,
CA_UNBAN,
CA_AUTOOP,
CA_OPDEOPME,
CA_OPDEOP,
CA_AUTOPROTECT,
CA_AKICK,
CA_BADWORDS,
CA_ASSIGN,
CA_MEMO,
CA_ACCESS_CHANGE,
CA_PROTECTME,
CA_PROTECT,
CA_SET,
CA_AUTOOWNER,
CA_OWNERME,
CA_OWNER,
CA_FOUNDER,
CA_SIZE
ACCESS_INVALID = -10000,
ACCESS_FOUNDER = 10001
};
struct CoreExport Privilege
{
Anope::string name;
Anope::string desc;
int rank;
Privilege(const Anope::string &n, const Anope::string &d, int r);
bool operator==(const Privilege &other) const;
};
class CoreExport PrivilegeManager
{
static std::vector<Privilege> privs;
public:
static void AddPrivilege(Privilege p);
static void RemovePrivilege(Privilege &p);
static Privilege *FindPrivilege(const Anope::string &name);
static std::vector<Privilege> &GetPrivileges();
static void ClearPrivileges();
};
class ChanAccess;
@@ -52,7 +38,7 @@ class CoreExport AccessProvider : public Service
virtual ChanAccess *Create() = 0;
};
class CoreExport ChanAccess
class CoreExport ChanAccess : public Serializable
{
public:
AccessProvider *provider;
@@ -64,15 +50,20 @@ class CoreExport ChanAccess
ChanAccess(AccessProvider *p);
virtual ~ChanAccess();
virtual bool Matches(User *u, NickCore *nc) = 0;
virtual bool HasPriv(ChannelAccess priv) = 0;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
virtual bool Matches(User *u, NickCore *nc);
virtual bool HasPriv(const Anope::string &name) const = 0;
virtual Anope::string Serialize() = 0;
virtual void Unserialize(const Anope::string &data) = 0;
bool operator>(ChanAccess &other);
bool operator<(ChanAccess &other);
bool operator>=(ChanAccess &other);
bool operator<=(ChanAccess &other);
bool operator>(const ChanAccess &other) const;
bool operator<(const ChanAccess &other) const;
bool operator>=(const ChanAccess &other) const;
bool operator<=(const ChanAccess &other) const;
};
class CoreExport AccessGroup : public std::vector<ChanAccess *>
@@ -82,7 +73,7 @@ class CoreExport AccessGroup : public std::vector<ChanAccess *>
NickCore *nc;
bool SuperAdmin, Founder;
AccessGroup();
bool HasPriv(ChannelAccess priv) const;
bool HasPriv(const Anope::string &priv) const;
ChanAccess *Highest() const;
bool operator>(const AccessGroup &other) const;
bool operator<(const AccessGroup &other) const;
+11 -5
View File
@@ -93,9 +93,7 @@ const Anope::string NickCoreFlagStrings[] = {
"MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "FORBIDDEN", "UNCONFIRMED", ""
};
class NickCore;
class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag, NS_END>
class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag, NS_END>, public Serializable
{
public:
/** Default constructor
@@ -118,6 +116,10 @@ class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag, NS_EN
NickCore *nc; /* I'm an alias of this */
HostInfo hostinfo;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
/** Release a nick
* See the comment in users.cpp
*/
@@ -131,7 +133,7 @@ class CoreExport NickAlias : public Extensible, public Flags<NickNameFlag, NS_EN
void OnCancel(User *u);
};
class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END>
class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END>, public Serializable
{
public:
/** Default constructor
@@ -153,14 +155,18 @@ class CoreExport NickCore : public Extensible, public Flags<NickCoreFlag, NI_END
std::vector<Anope::string> access; /* Access list, vector of strings */
std::vector<Anope::string> cert; /* ssl certificate list, vector of strings */
MemoInfo memos;
uint16 channelcount; /* Number of channels currently registered */
Oper *o;
/* Unsaved data */
uint16_t channelcount; /* Number of channels currently registered */
time_t lastmail; /* Last time this nick record got a mail */
std::list<NickAlias *> aliases; /* List of aliases */
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
/** Checks whether this account is a services oper or not.
* @return True if this account is a services oper, false otherwise.
*/
+31 -3
View File
@@ -1,5 +1,5 @@
/*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -21,7 +21,7 @@ class Message;
namespace Anope
{
template<typename T> class map : public std::map<string, T> { };
template<typename T> class insensitive_map : public std::map<string, T, std::less<ci::string> > { };
template<typename T> class insensitive_map : public std::map<string, T, ci::less> { };
/**
* A wrapper string class around all the other string classes, this class will
@@ -258,6 +258,28 @@ namespace Anope
return new_string;
}
/**
* Get the string in lowercase.
*/
inline string lower()
{
Anope::string new_string = *this;
for (size_type i = 0; i < new_string.length(); ++i)
new_string[i] = static_cast<char>(tolower(new_string[i]));
return new_string;
}
/**
* Get the string in uppercase.
*/
inline string upper()
{
Anope::string new_string = *this;
for (size_type i = 0; i < new_string.length(); ++i)
new_string[i] = static_cast<char>(toupper(new_string[i]));
return new_string;
}
/**
* Get a substring of the string.
*/
@@ -462,7 +484,7 @@ class CoreExport Base
void DelReference(dynamic_reference_base *r);
};
class dynamic_reference_base : public Base
class dynamic_reference_base
{
protected:
bool invalid;
@@ -484,6 +506,12 @@ class dynamic_reference : public dynamic_reference_base
ref->AddReference(this);
}
dynamic_reference(const dynamic_reference<T> &obj) : ref(obj.ref)
{
if (ref)
ref->AddReference(this);
}
virtual ~dynamic_reference()
{
if (this->invalid)
+8 -3
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
* Copyright (C) 2008-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -32,15 +32,16 @@ enum BotFlag
static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "CONF", "" };
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>, public Serializable
{
public:
uint32 chancount;
uint32_t chancount;
time_t created; /* Birth date ;) */
time_t lastmsg; /* Last time we said something */
typedef Anope::insensitive_map<CommandInfo> command_map;
command_map commands; /* Commands, actual name to service name */
Anope::string botmodes; /* Modes the bot should have as configured in service:modes */
std::vector<Anope::string> botchannels; /* Channels the bot should be in as configured in service:channels */
bool introduced; /* Whether or not this bot is introduced */
/** Create a new bot.
@@ -56,6 +57,10 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END>
*/
virtual ~BotInfo();
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
void GenerateUID();
/** Change the nickname for the bot.
+7 -9
View File
@@ -1,6 +1,6 @@
/* Channel support
*
* (C) 2008-2011 Anope Team
* (C) 2008-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -30,12 +30,10 @@ enum ChannelFlag
/* Channel still exists when emptied */
CH_PERSIST,
/* If set the channel is syncing users (channel was just created) and it should not be deleted */
CH_SYNCING,
/* Is a services log channel */
CH_LOGCHAN
CH_SYNCING
};
const Anope::string ChannelFlagString[] = { "CH_INABIT", "CH_PERSIST", "CH_SYNCING", "CH_LOGCHAN", "" };
const Anope::string ChannelFlagString[] = { "CH_INABIT", "CH_PERSIST", "CH_SYNCING", "" };
class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
{
@@ -45,7 +43,7 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
/** A map of channel modes with their parameters set on this channel
*/
ModeList modes;
public:
/** Default constructor
* @param name The channel name
@@ -70,9 +68,9 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlag, 3>
time_t server_modetime; /* Time of last server MODE */
time_t chanserv_modetime; /* Time of last check_modes() */
int16 server_modecount; /* Number of server MODEs this second */
int16 chanserv_modecount; /* Number of check_mode()'s this sec */
int16 bouncy_modes; /* Did we fail to set modes here? */
int16_t server_modecount; /* Number of server MODEs this second */
int16_t chanserv_modecount; /* Number of check_mode()'s this sec */
int16_t bouncy_modes; /* Did we fail to set modes here? */
/** Call if we need to unset all modes and clear all user status (internally).
* Only useful if we get a SJOIN with a TS older than what we have here
+1 -5
View File
@@ -1,6 +1,6 @@
/* Declarations for command data.
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -52,12 +52,8 @@ struct CoreExport CommandSource
/* The permission of the command being executed */
Anope::string permission;
std::list<Anope::string> reply;
void Reply(const char *message, ...);
void Reply(const Anope::string &message);
void DoReply();
};
/** Every services command is a class, inheriting from Command.
+19 -5
View File
@@ -41,7 +41,8 @@ enum ConfigDataType
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_STRING
DT_ALLOW_NEWLINE = 128, // New line characters allowed in DT_STRING
DT_ALLOW_EMPTY = 256 // Allow empty value
};
/** Holds a config value, either string, integer or boolean.
@@ -423,6 +424,8 @@ class CoreExport ServerConfig
int RetryWait;
/* If services should hide unprivileged commands */
bool HidePrivilegedCommands;
/* If set, nicks cant be owned/everything is entirely account based */
bool NoNicknameOwnership;
/* A vector of our logfile options */
std::vector<LogInfo *> LogInfos;
@@ -439,6 +442,12 @@ class CoreExport ServerConfig
time_t MailDelay;
/* Don't quote the To: address */
bool DontQuoteAddresses;
/* Mail messages to send */
Anope::string MailRegistrationSubject, MailRegistrationMessage;
Anope::string MailResetSubject, MailResetMessage;
Anope::string MailSendpassSubject, MailSendpassMessage;
Anope::string MailEmailchangeSubject, MailEmailchangeMessage;
Anope::string MailMemoSubject, MailMemoMessage;
/* Nameserver to use for resolving hostnames */
Anope::string NameServer;
@@ -535,6 +544,13 @@ class CoreExport ServerConfig
/* Who can use memos reciepts */
unsigned MSMemoReceipt;
/* Valid chars allowed in vhosts */
Anope::string VhostChars;
/* Allow undotted vhosts? */
bool VhostUndotted;
/* Chars disallowed at the beginning or end of vhosts */
Anope::string VhostDisallowBE;
/* Core BotServ modules */
Anope::string BotCoreModules;
/* Default BotServ flags */
@@ -576,8 +592,6 @@ class CoreExport ServerConfig
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 */
@@ -594,12 +608,12 @@ class CoreExport ServerConfig
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;
/* Add the akillers nick to the akill reason */
bool AddAkiller;
/* Add akill ids to akill reason */
bool AkillIds;
/* Limit sessions */
bool LimitSessions;
+74 -77
View File
@@ -19,7 +19,7 @@ enum QueryType
/** Flags that can be AND'd into DNSPacket::flags to receive certain values
*/
enum QueryFlags
enum
{
DNS_QUERYFLAGS_QR = 0x8000,
DNS_QUERYFLAGS_OPCODE = 0x7800,
@@ -48,16 +48,45 @@ enum DNSError
DNS_ERROR_INVALIDTYPE
};
class DNSRequestTimeout; // Forward declarations
struct DNSRecord;
class Module;
struct DNSQuery;
class DNSPacket;
struct CoreExport Question
{
Anope::string name;
QueryType type;
unsigned short qclass;
Question();
Question(const Anope::string &, QueryType, unsigned short = 1);
};
struct CoreExport ResourceRecord : public Question
{
unsigned int ttl;
Anope::string rdata;
time_t created;
ResourceRecord(const Anope::string &, QueryType, unsigned short = 1);
ResourceRecord(const Question &);
};
struct CoreExport DNSQuery
{
std::vector<Question> questions;
std::vector<ResourceRecord> answers, authorities, additional;
DNSError error;
DNSQuery();
DNSQuery(const Question &q);
DNSQuery(const DNSPacket &p);
};
/** The request
*/
class CoreExport DNSRequest
class CoreExport DNSRequest : public Timer, public Question
{
/* Timeout timer for this request */
DNSRequestTimeout *timeout;
/* Use result cache if available */
bool use_cache;
@@ -67,81 +96,50 @@ class CoreExport DNSRequest
/* Creator of this request */
Module *creator;
/* Address we're looking up */
Anope::string address;
/* QueryType, A, AAAA, PTR etc */
QueryType QT;
DNSRequest(const Anope::string &addr, QueryType qt, bool cache = false, Module *c = NULL);
virtual ~DNSRequest();
void Process();
virtual void OnLookupComplete(const DNSRecord *r) = 0;
virtual void OnLookupComplete(const DNSQuery *r) = 0;
virtual void OnError(const DNSRecord *r);
virtual void OnError(const DNSQuery *r);
void Tick(time_t);
};
/** A full packet sent to the nameserver, may contain multiple queries
/** A full packet sent or recieved to/from the nameserver, may contain multiple queries
*/
struct DNSPacket
class DNSPacket : public DNSQuery
{
static const int DNS_POINTER = 0xC0;
static const int DNS_LABEL = 0x3F;
void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name);
Anope::string UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos);
Question UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos);
ResourceRecord UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &poss);
public:
static const int HEADER_LENGTH = 12;
/* Our 16-bit id for this header */
unsigned short id;
/* Flags on the query */
unsigned short flags;
/* Number of queries */
unsigned short qdcount;
/* Number of resource records in answer */
unsigned short ancount;
/* Number of NS resource records in authority records section */
unsigned short nscount;
/* Number of resource records in the additional records section */
unsigned short arcount;
/* How many of the bytes of the payload are in use */
unsigned short payload_count;
/* The queries, at most can be 512 bytes */
unsigned char payload[512];
inline DNSPacket();
bool AddQuestion(const Anope::string &address, QueryType qt);
inline void FillPacket(const unsigned char *input, const size_t length);
inline void FillBuffer(unsigned char *buffer);
DNSPacket();
void Fill(const unsigned char *input, const unsigned short len);
unsigned short Pack(unsigned char *output, unsigned short output_size);
};
struct CoreExport DNSRecord
{
/* Name of the initial lookup */
Anope::string name;
/* Result of the lookup */
Anope::string result;
/* Type of query this was */
QueryType type;
/* Error, if there was one */
DNSError error;
/* Record class, should always be 1 */
unsigned short record_class;
/* Time to live */
time_t ttl;
/* Record length */
unsigned short rdlength;
/* When this record was created in our cache */
time_t created;
inline DNSRecord(const Anope::string &n);
operator bool() const;
};
/** DNS manager, manages the connection and all requests
/** DNS manager, manages all requests
*/
class CoreExport DNSManager : public Timer, public Socket
{
std::multimap<Anope::string, DNSRecord *> cache;
typedef std::multimap<Anope::string, ResourceRecord, ci::less> cache_map;
cache_map cache;
sockaddrs addrs;
public:
std::deque<DNSPacket *> packets;
@@ -157,35 +155,34 @@ class CoreExport DNSManager : public Timer, public Socket
bool ProcessWrite();
void AddCache(DNSRecord *rr);
/** Add a record to the dns cache
* @param r The record
*/
void AddCache(DNSQuery &r);
/** Check the DNS cache to see if request can be handled by a cached result
* @return true if a cached result was found.
*/
bool CheckCache(DNSRequest *request);
/** Tick this timer, used to clear the DNS cache.
*/
void Tick(time_t now);
/** Cleanup all pending DNS queries for a module
* @param mod The module
*/
void Cleanup(Module *mod);
/** Does a BLOCKING DNS query and returns the first IP.
* Only use this if you know what you are doing. Unless you specifically
* need a blocking query use the DNSRequest system
*/
static DNSRecord BlockingQuery(const Anope::string &mask, QueryType qt);
};
/** A DNS timeout, one is made for every DNS request to detect timeouts
*/
class DNSRequestTimeout : public Timer
{
DNSRequest *request;
public:
bool done;
DNSRequestTimeout(DNSRequest *r, time_t timeout);
~DNSRequestTimeout();
void Tick(time_t);
static DNSQuery BlockingQuery(const Anope::string &mask, QueryType qt);
};
extern DNSManager *DNSEngine;
#endif // DNS_H
+39 -135
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
* Copyright (C) 2008-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -7,61 +7,28 @@
#ifndef EXTENSIBLE_H
#define EXTENSIBLE_H
#include "anope.h"
#include "hashcomp.h"
/** Dummy base class we use to cast everything to/from
*/
class ExtensibleItemBase
class CoreExport ExtensibleItem
{
public:
ExtensibleItemBase() { }
virtual ~ExtensibleItemBase() { }
ExtensibleItem();
virtual ~ExtensibleItem();
virtual void OnDelete();
};
/** Class used to represent an extensible item that doesn't hold a pointer
*/
template<typename T> class ExtensibleItemRegular : public ExtensibleItemBase
class ExtensibleString : public Anope::string, public ExtensibleItem
{
protected:
T Item;
public:
ExtensibleItemRegular(T item) : Item(item) { }
virtual ~ExtensibleItemRegular() { }
T &GetItem() { return Item; }
};
/** Class used to represent an extensible item that holds a pointer
*/
template<typename T> class ExtensibleItemPointer : public ExtensibleItemBase
{
protected:
T *Item;
public:
ExtensibleItemPointer(T *item) : Item(item) { }
virtual ~ExtensibleItemPointer() { delete Item; }
T *GetItem() { return Item; }
};
/** Class used to represent an extensible item that holds a pointer to an arrray
*/
template<typename T> class ExtensibleItemPointerArray : public ExtensibleItemBase
{
protected:
T *Item;
public:
ExtensibleItemPointerArray(T *item) : Item(item) { }
virtual ~ExtensibleItemPointerArray() { delete [] Item; }
T *GetItem() { return Item; }
ExtensibleString(const Anope::string &s) : Anope::string(s), ExtensibleItem() { }
};
class CoreExport Extensible : public Base
{
private:
typedef std::map<Anope::string, ExtensibleItemBase *> extensible_map;
extensible_map Extension_Items;
typedef Anope::map<ExtensibleItem *> extensible_map;
extensible_map extension_items;
public:
/** Default constructor, does nothing
@@ -73,9 +40,10 @@ class CoreExport Extensible : public Base
*/
virtual ~Extensible()
{
for (extensible_map::iterator it = Extension_Items.begin(), it_end = Extension_Items.end(); it != it_end; ++it)
delete it->second;
Extension_Items.clear();
for (extensible_map::iterator it = extension_items.begin(), it_end = extension_items.end(); it != it_end; ++it)
if (it->second)
it->second->OnDelete();
extension_items.clear();
}
/** Extend an Extensible class.
@@ -89,26 +57,10 @@ class CoreExport Extensible : public Base
*
* @return Returns true on success, false if otherwise
*/
void Extend(const Anope::string &key, ExtensibleItemBase *p)
void Extend(const Anope::string &key, ExtensibleItem *p)
{
this->Shrink(key);
this->Extension_Items.insert(std::make_pair(key, p));
}
/** Extend an Extensible class.
*
* @param key The key parameter is an arbitary string which identifies the extension data
*
* You must provide a key to store the data as via the parameter 'key', this single-parameter
* version takes no 'data' parameter, this is used purely for boolean values.
* The key will be inserted into the map with a NULL 'data' pointer. If the key already exists
* then you may not insert it twice, Extensible::Extend will return false in this case.
*
* @return Returns true on success, false if otherwise
*/
void Extend(const Anope::string &key)
{
this->Extend(key, new ExtensibleItemPointer<char *>(NULL));
this->extension_items[key] = p;
}
/** Shrink an Extensible class.
@@ -121,91 +73,43 @@ class CoreExport Extensible : public Base
*/
bool Shrink(const Anope::string &key)
{
extensible_map::iterator it = this->Extension_Items.find(key);
if (it != this->Extension_Items.end())
extensible_map::iterator it = this->extension_items.find(key);
if (it != this->extension_items.end())
{
delete it->second;
if (it->second != NULL)
it->second->OnDelete();
/* map::size_type map::erase( const key_type& key );
* returns the number of elements removed, std::map
* is single-associative so this should only be 0 or 1
*/
return this->Extension_Items.erase(key);
return this->extension_items.erase(key) > 0;
}
return false;
}
/** Get an extension item that is not a pointer.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @param p If you provide a non-existent key, this value will be 0. Otherwise a copy to the item you requested will be placed in this templated parameter.
* @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
*/
template<typename T> bool GetExtRegular(const Anope::string &key, T &p)
{
extensible_map::iterator it = this->Extension_Items.find(key);
if (it != this->Extension_Items.end())
{
p = debug_cast<ExtensibleItemRegular<T> *>(it->second)->GetItem();
return true;
}
return false;
}
/** Get an extension item that is a pointer.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* * @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
* @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
*/
template<typename T> bool GetExtPointer(const Anope::string &key, T *&p)
{
extensible_map::iterator it = this->Extension_Items.find(key);
if (it != this->Extension_Items.end())
{
p = debug_cast<ExtensibleItemPointer<T> *>(it->second)->GetItem();
return true;
}
p = NULL;
return false;
}
/** Get an extension item that is a pointer to an array
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @param p If you provide a non-existent key, this value will be NULL. Otherwise a pointer to the item you requested will be placed in this templated parameter.
* @return Returns true if the item was found and false if it was nor, regardless of wether 'p' is NULL. This allows you to store NULL values in Extensible.
*/
template<typename T> bool GetExtArray(const Anope::string &key, T *&p)
{
extensible_map::iterator it = this->Extension_Items.find(key);
if (it != this->Extension_Items.end())
{
p = debug_cast<ExtensibleItemPointerArray<T> *>(it->second)->GetItem();
return true;
}
p = NULL;
return false;
}
/** Get an extension item.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @return Returns true if the item was found and false if it was not.
*
* This single-parameter version only checks if the key exists, it does nothing with
* the 'data' field and is probably only useful in conjunction with the single-parameter
* version of Extend().
* @return The item found
*/
bool GetExt(const Anope::string &key)
template<typename T> T GetExt(const Anope::string &key)
{
return this->Extension_Items.find(key) != this->Extension_Items.end();
extensible_map::iterator it = this->extension_items.find(key);
if (it != this->extension_items.end())
return debug_cast<T>(it->second);
return NULL;
}
/** Check if an extension item exists.
*
* @param key The key parameter is an arbitary string which identifies the extension data
* @return True if the item was found.
*/
bool HasExt(const Anope::string &key)
{
return this->extension_items.count(key) > 0;
}
/** Get a list of all extension items names.
@@ -215,7 +119,7 @@ class CoreExport Extensible : public Base
*/
void GetExtList(std::deque<Anope::string> &list)
{
for (extensible_map::iterator it = Extension_Items.begin(), it_end = Extension_Items.end(); it != it_end; ++it)
for (extensible_map::iterator it = extension_items.begin(), it_end = extension_items.end(); it != it_end; ++it)
list.push_back(it->first);
}
};
+37 -20
View File
@@ -1,6 +1,6 @@
/* Prototypes and external variable declarations.
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -74,6 +74,8 @@ E bool enc_decrypt(const Anope::string &src, Anope::string &dest);
E void introduce_user(const Anope::string &user);
E bool GetCommandLineArgument(const Anope::string &name, char shortname = 0);
E bool GetCommandLineArgument(const Anope::string &name, char shortname, Anope::string &param);
E bool AtTerm();
E void Fork();
E void Init(int ac, char **av);
/**** ircd.c ****/
@@ -102,11 +104,36 @@ E bool noexpire;
E bool protocoldebug;
E bool quitting;
E int return_code;
E bool restarting;
E Anope::string quitmsg;
E time_t start_time;
E ConnectionSocket *UplinkSock;
class UplinkSocket : public ConnectionSocket, public BufferedSocket
{
public:
UplinkSocket();
~UplinkSocket();
bool Read(const Anope::string &);
void OnConnect();
void OnError(const Anope::string &);
class CoreExport Message
{
Anope::string source;
std::stringstream buffer;
public:
Message();
Message(const Anope::string &);
~Message();
template<typename T> Message &operator<<(const T &val)
{
this->buffer << val;
return *this;
}
};
};
E UplinkSocket *UplinkSock;
E int CurrentUplink;
E void save_databases();
@@ -143,17 +170,13 @@ E bool OnError(const Anope::string &, const std::vector<Anope::string> &);
/**** misc.c ****/
E bool IsFile(const Anope::string &filename);
E int toupper(char);
E int tolower(char);
E time_t dotime(const Anope::string &s);
E Anope::string duration(const time_t &seconds, NickCore *nc = NULL);
E Anope::string expire_left(NickCore *nc, time_t expires);
E Anope::string do_strftime(const time_t &t, NickCore *nc = NULL, bool short_output = false);
E bool doValidHost(const Anope::string &host, int type);
E bool isValidHost(const Anope::string &host, int type);
E bool isvalidchar(char c);
E bool IsValidIdent(const Anope::string &ident);
E bool IsValidHost(const Anope::string &host);
E Anope::string myStrGetToken(const Anope::string &str, char dilim, int token_number);
E Anope::string myStrGetTokenRemainder(const Anope::string &str, char dilim, int token_number);
@@ -163,8 +186,8 @@ E bool nickIsServices(const Anope::string &nick, bool bot);
E void add_entropy_userkeys();
E void rand_init();
E unsigned char getrandom8();
E uint16 getrandom16();
E uint32 getrandom32();
E uint16_t getrandom16();
E uint32_t getrandom32();
E std::list<Anope::string> BuildStringList(const Anope::string &, char = ' ');
E std::vector<Anope::string> BuildStringVector(const Anope::string &, char = ' ');
@@ -192,22 +215,16 @@ E bool is_on_access(const User *u, const NickCore *nc);
E void process(const Anope::string &buf);
/**** send.c ****/
E void send_cmd(const Anope::string &source, const char *fmt, ...) FORMAT(printf, 2, 3);
E void notice_server(const Anope::string &source, const Server *s, const char *fmt, ...) FORMAT(printf, 3, 4);
/**** sockets.cpp ****/
E int32 TotalRead;
E int32 TotalWritten;
E int32_t TotalRead;
E int32_t TotalWritten;
E SocketIO normalSocketIO;
/**** users.c ****/
E int32 opcnt;
E uint32 maxusercnt, usercnt;
E int32_t opcnt;
E uint32_t maxusercnt, usercnt;
E time_t maxusertime;
E User *finduser(const Anope::string &nick);
+8 -133
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2011 InspIRCd Development Team
* Copyright (C) 2009-2011 Anope Team <team@anope.org>
* Copyright (C) 2009-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*
@@ -33,34 +33,6 @@ namespace Anope
class string;
}
#ifndef _WIN32
# if defined(__GNUC__) && __GNUC__ >= 4
/* GCC4+ 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 /* GCC ver < 4 */
# include <ext/hash_map>
/* Oddball linux namespace for hash_map */
# define unordered_map_namespace __gnu_cxx
# define unordered_map hash_map
# endif
#else
# if _MSC_VER >= 1600
/* MSVC 2010+ has tr1. Though MSVC and GCC use different includes! */
# include <unordered_map>
# define unordered_map_namespace std::tr1
# else
# include <hash_map>
# define unordered_map_namespace
template<typename Key, typename Type, typename Compare, typename Unused = void>
class unordered_map : public stdext::hash_map<Key, Type, Compare>
{
public:
unordered_map() : hash_map() { }
};
# endif
#endif
/*******************************************************
* This file contains classes and templates that deal
* with the comparison and hashing of 'irc strings'.
@@ -168,21 +140,14 @@ namespace irc
*/
typedef std::basic_string<char, irc_char_traits, std::allocator<char> > string;
/** Used to hash irc::strings for unordered_map
*/
struct CoreExport hash
struct CoreExport less
{
/* VS 2008 specific code */
enum { bucket_size = 4, min_buckets = 8 };
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
/* End VS 2008 specific code */
/** Hash an irc::string for unordered_map
* @param s The string
* @return A hash value for the string
/** Compare two Anope::strings as irc::strings and find which one is less
* @param s1 The first string
* @param s2 The second string
* @return true if s1 < s2, else false
*/
size_t operator()(const irc::string &s) const;
size_t operator()(const Anope::string &s) const;
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
};
}
@@ -239,60 +204,8 @@ namespace ci
*/
typedef std::basic_string<char, ci_char_traits, std::allocator<char> > string;
/** Used to hash ci::strings for unordered_map
*/
struct CoreExport hash
struct CoreExport less
{
/* VS 2008 specific code */
enum { bucket_size = 4, min_buckets = 8 };
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
/* End VS 2008 specific code */
/** Hash a ci::string for unordered_map
* @param s The string
* @return A hash value for the string
*/
size_t operator()(const ci::string &s) const;
size_t operator()(const Anope::string &s) const;
};
}
namespace std
{
/** An overload for std::equal_to<ci::string> that uses Anope::string, passed for the fourth temmplate
* argument for unordered_map
*/
template<> struct CoreExport equal_to<ci::string>
{
public:
/** Compare two Anope::strings as ci::strings
* @paarm s1 The first string
* @param s2 The second string
* @return true if they are equal
*/
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
};
/** An overload for std::equal_to<irc::string> that uses Anope::string, passed for the fourth template
* argument for unorderd_map
*/
template<> struct CoreExport equal_to<irc::string>
{
public:
/** Compare two Anope::strings as irc::strings
* @param s1 The first string
* @param s2 The second string
* @return true if they are equal
*/
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
};
/** An overload for std::less<ci::string> that uses Anope::string, passed for the third template argument
* to std::map and std::multimap
*/
template<> struct CoreExport less<ci::string>
{
public:
/** Compare two Anope::strings as ci::strings and find which one is less
* @param s1 The first string
* @param s2 The second string
@@ -300,44 +213,6 @@ namespace std
*/
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
};
/** An overload for std;:less<irc::string> that uses Anope::string, passed for the third tempalte argument
* to std::map and std::multimap
*/
template<> struct CoreExport less<irc::string>
{
public:
/** Compare two Anope::strings as irc::strings and find which one is less
* @param s1 The first string
* @param s2 The second string
* @return true if s1 < s2, else false
*/
bool operator()(const Anope::string &s1, const Anope::string &s2) const;
};
}
/* Define operators for using >> and << with irc::string to an ostream on an istream. */
/* This was endless fun. No. Really. */
/* It was also the first core change Ommeh made, if anyone cares */
/** Operator >> for irc::string
*/
inline std::istream &operator>>(std::istream &is, irc::string &str)
{
std::string tmp;
is >> tmp;
str = tmp.c_str();
return is;
}
/** Operator >> for ci::string
*/
inline std::istream &operator>>(std::istream &is, ci::string &str)
{
std::string tmp;
is >> tmp;
str = tmp.c_str();
return is;
}
/* Define operators for + and == with irc::string to std::string for easy assignment
+1 -16
View File
@@ -1,6 +1,6 @@
/* Commonly used language strings
*
* (C) 2008-2011 Anope Team
* (C) 2008-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -30,7 +30,6 @@
#define NO_REASON _("No reason")
#define UNKNOWN _("<unknown>")
#define NO_EXPIRE _("does not expire")
#define END_OF_ANY_LIST _("End of \002%s\002 list.")
#define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.")
#define UNKNOWN_OPTION _("Unknown option \002%s\002.\n" \
"Type %s%s HELP %s for more information.")
@@ -47,7 +46,6 @@
#define NICK_SET_UNKNOWN_OPTION _("Unknown SET option \002%s%s\002.")
#define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.")
#define NICK_LIST_SYNTAX _("LIST \037pattern\037")
#define LIST_HEADER _("List of entries matching \002%s\002:")
#define NICK_RECOVERED _("User claiming your nick has been killed.\n" \
"\002%s%s RELEASE %s\002 to get it back before %s timeout.")
#define NICK_REQUESTED _("This nick has already been requested, please check your e-mail address for the pass code")
@@ -62,16 +60,8 @@
#define CHAN_SETTING_UNSET _("%s for %s unset.")
#define CHAN_SET_MLOCK_DEPRECATED _("MLOCK is deprecated. Use \002%s%s HELP MODE\002 instead.")
#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.")
#define CHAN_ACCESS_LIST_HEADER _("Access list for %s:\n" \
" Num Lev Mask")
#define CHAN_ACCESS_VIEW_AXS_FORMAT _(" %3d %4d %s\n" \
" by %s on %s, last seen %s")
#define CHAN_AKICK_VIEW_FORMAT _("%3d %s (by %s on %s)\n" \
" %s")
#define CHAN_INFO_HEADER _("Information for channel \002%s\002:")
#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except have been removed.")
#define CHAN_LIST_ENTRY _("%3d %s\n" \
" Added by %s on %s")
#define MEMO_NEW_X_MEMO_ARRIVED _("There is a new memo on channel %s.\n" \
"Type \002%s%s READ %s %d\002 to read it.")
#define MEMO_NEW_MEMO_ARRIVED _("You have a new memo from %s.\n" \
@@ -86,11 +76,6 @@
#define BOT_NOT_ASSIGNED _("You must assign a bot to the channel before using this command.")
#define BOT_NOT_ON_CHANNEL _("Bot is not on channel \002%s\002.")
#define BOT_ASSIGN_READONLY _("Sorry, bot assignment is temporarily disabled.")
#define ENABLED _("Enabled")
#define DISABLED _("Disabled")
#define OPER_LIST_FORMAT _(" %3d %-32s %s")
#define OPER_VIEW_FORMAT _("%3d %s (by %s on %s; %s)\n" \
" %s")
#define HOST_SET_ERROR _("A vhost must be in the format of a valid hostmask.")
#define HOST_SET_IDENT_ERROR _("A vhost ident must be in the format of a valid ident")
#define HOST_SET_TOOLONG _("Error! The vhost is too long, please use a host shorter than %d characters.")
+8 -2
View File
@@ -35,6 +35,11 @@ class CoreExport Log
{
public:
BotInfo *bi;
User *u;
Command *c;
Channel *chan;
ChannelInfo *ci;
Server *s;
LogType Type;
Anope::string Category;
std::list<Anope::string> Sources;
@@ -59,6 +64,8 @@ class CoreExport Log
~Log();
Anope::string BuildPrefix() const;
template<typename T> Log &operator<<(T val)
{
this->buf << val;
@@ -73,7 +80,6 @@ class CoreExport LogInfo
std::map<Anope::string, LogFile *> Logfiles;
std::list<Anope::string> Sources;
int LogAge;
bool Inhabit;
std::list<Anope::string> Admin;
std::list<Anope::string> Override;
std::list<Anope::string> Commands;
@@ -84,7 +90,7 @@ class CoreExport LogInfo
bool RawIO;
bool Debug;
LogInfo(int logage, bool inhabit, bool rawio, bool debug);
LogInfo(int logage, bool rawio, bool debug);
~LogInfo();
+20 -5
View File
@@ -1,7 +1,7 @@
/* Mode support
*
* Copyright (C) 2008-2011 Adam <Adam@anope.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
* Copyright (C) 2008-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -19,7 +19,7 @@ enum UserModeName
UMODE_REGPRIV, UMODE_PROTECTED, UMODE_NO_CTCP, UMODE_WEBTV, UMODE_WEBIRC, UMODE_WHOIS, UMODE_ADMIN, UMODE_DEAF,
UMODE_GLOBOPS, UMODE_HELPOP, UMODE_INVIS, UMODE_OPER, UMODE_PRIV, UMODE_GOD, UMODE_REGISTERED,
UMODE_SNOMASK, UMODE_VHOST, UMODE_WALLOPS, UMODE_CLOAK, UMODE_SSL, UMODE_SOFTCALLERID, UMODE_CALLERID,
UMODE_COMMONCHANS, UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER, UMODE_RESTRICTED,
UMODE_COMMONCHANS, UMODE_HIDDEN, UMODE_STRIPCOLOR, UMODE_INVISIBLE_OPER, UMODE_RESTRICTED, UMODE_HIDEIDLE,
UMODE_END
};
@@ -31,7 +31,7 @@ const Anope::string UserModeNameStrings[] = {
"UMODE_REGPRIV", "UMODE_PROTECTED", "UMODE_NO_CTCP", "UMODE_WEBTV", "UMODE_WEBIRC", "UMODE_WHOIS", "UMODE_ADMIN", "UMODE_DEAF",
"UMODE_GLOBOPS", "UMODE_HELPOP", "UMODE_INVIS", "UMODE_OPER", "UMODE_PRIV", "UMODE_GOD", "UMODE_REGISTERED",
"UMODE_SNOMASK", "UMODE_VHOST", "UMODE_WALLOPS", "UMODE_CLOAK", "UMODE_SSL", "UMODE_SOFTCALLERID", "UMODE_CALLERID",
"UMODE_COMMONCHANS", "UMODE_HIDDEN", "UMODE_STRIPCOLOR", "UMODE_INVISIBLE_OPER", "UMODE_RESTRICTED"
"UMODE_COMMONCHANS", "UMODE_HIDDEN", "UMODE_STRIPCOLOR", "UMODE_INVISIBLE_OPER", "UMODE_RESTRICTED", "UMODE_HIDEIDLE",
""
};
@@ -276,13 +276,18 @@ class CoreExport ChannelModeStatus : public ChannelMode
public:
/* The symbol, eg @ % + */
char Symbol;
/* The "level" of the mode, used to compare with other modes.
* Used so we know op > halfop > voice etc.
*/
unsigned short Level;
/** Default constructor
* @param mName The mode name
* @param modeChar The mode char
* @param mSymbol The symbol for the mode, eg @ % +
* @param mSymbol The symbol for the mode, eg @ %
* @param mLevel A level for the mode, which is usually determined by the PREFIX capab
*/
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol);
ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol, unsigned short mLevel = 0);
/** Default destructor
*/
@@ -370,6 +375,16 @@ class StackerInfo
class CoreExport ModeManager
{
protected:
class ModePipe : public Pipe
{
public:
/** Called when there are modes to be set
*/
void OnNotify();
};
static ModePipe *mpipe;
/* List of pairs of user/channels and their stacker info */
static std::list<std::pair<Base *, StackerInfo *> > StackerObjects;
+34 -153
View File
@@ -1,6 +1,6 @@
/* Modular support
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,27 +18,6 @@
#include "timers.h"
#include "hashcomp.h"
/* Cross OS compatibility macros */
#ifdef _WIN32
typedef HMODULE ano_module_t;
# define dlopen(file, unused) LoadLibrary(file)
# define dlsym(file, symbol) (HMODULE)GetProcAddress(file, symbol)
# define dlclose(file) FreeLibrary(file) ? 0 : 1
# define ano_modclearerr() SetLastError(0)
# define ano_moderr() (Anope::LastError().empty() ? NULL : Anope::LastError().c_str())
#else
typedef void * ano_module_t;
/* We call dlerror() here because it clears the module error after being
* called. This previously read 'errno = 0', but that didn't work on
* all POSIX-compliant architectures. This way the error is guaranteed
* to be cleared, POSIX-wise. -GD
*/
# define ano_modclearerr() dlerror()
# define ano_moderr() dlerror()
#endif
/** Possible return types from events.
*/
enum EventReturn
@@ -215,7 +194,7 @@ class CoreExport Module : public Extensible
/** Handle for this module, obtained from dlopen()
*/
ano_module_t handle;
void *handle;
/** Time this module was created
*/
@@ -317,8 +296,9 @@ class CoreExport Module : public Extensible
/** Called when someone uses the generic/help command
* @param source Command source
* @param params Params
* @return EVENT_STOP to stop processing
*/
virtual void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) { }
virtual EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when someone uses the generic/help command
* @param source Command source
@@ -341,11 +321,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params) { }
/** Called after the core has finished loading the databases, but before
* we connect to the server
*/
virtual void OnPostLoadDatabases() { }
/** Called when the databases are saved
* @return EVENT_CONTINUE to let other modules continue saving, EVENT_STOP to stop
*/
@@ -459,9 +434,9 @@ class CoreExport Module : public Extensible
/** Called before a channel expires
* @param ci The channel
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
* @param expire Set to true to allow the chan to expire
*/
virtual EventReturn OnPreChanExpire(ChannelInfo *ci) { return EVENT_CONTINUE; }
virtual void OnPreChanExpire(ChannelInfo *ci, bool &expire) { }
/** Called before a channel expires
* @param ci The channel
@@ -484,73 +459,6 @@ class CoreExport Module : public Extensible
*/
virtual void OnServerDisconnect() { }
/** Called when the flatfile dbs are being written
* @param Write A callback to the function used to insert a line into the database
*/
virtual void OnDatabaseWrite(void (*Write)(const Anope::string &)) { }
/** Called when a line is read from the database
* @param params The params from the database
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing
*/
virtual EventReturn OnDatabaseRead(const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when nickcore metadata is read from the database
* @param nc The nickcore
* @param 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(NickCore *nc, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when nickcore metadata is read from the database
* @param na The nickalias
* @param 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(NickAlias *na, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when botinfo metadata is read from the database
* @param bi The botinfo
* @param 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(BotInfo *bi, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when chaninfo metadata is read from the database
* @param ci The chaninfo
* @param 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(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> &params) { return EVENT_CONTINUE; }
/** Called when we are writing metadata for a nickcore
* @param WriteMetata A callback function used to insert the metadata
* @param nc The nickcore
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickCore *nc) { }
/** Called when we are wrting metadata for a nickalias
* @param WriteMetata A callback function used to insert the metadata
* @param na The nick alias
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickAlias *na) { }
/** Called when we are writing metadata for a botinfo
* @param WriteMetata A callback function used to insert the metadata
* @param bi The botinfo
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), BotInfo *bi) { }
/** Called when are are writing metadata for a channelinfo
* @param WriteMetata A callback function used to insert the metadata
* @param bi The channelinfo
*/
virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci) { }
/** Called when services restart
*/
virtual void OnRestart() { }
@@ -561,9 +469,9 @@ class CoreExport Module : public Extensible
/** Called before a nick expires
* @param na The nick
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to halt the command and not process it
* @param expire Set to true to allow the nick to expire
*/
virtual EventReturn OnPreNickExpire(NickAlias *na) { return EVENT_CONTINUE; }
virtual void OnPreNickExpire(NickAlias *na, bool &expire) { }
/** Called when a nick drops
* @param na The nick
@@ -662,21 +570,16 @@ class CoreExport Module : public Extensible
/** Called when a level for a channel is changed
* @param u The user changing the level
* @param ci The channel the level was changed on
* @param pos The level position, can be -1 for resetting levels
* @param priv The privilege changed
* @param what The new level
*/
virtual void OnLevelChange(User *u, ChannelInfo *ci, int pos, int what) { }
virtual void OnLevelChange(User *u, ChannelInfo *ci, const Anope::string &priv, int16_t what) { }
/** Called when a channel is dropped
* @param chname The channel name
*/
virtual void OnChanDrop(const Anope::string &chname) { }
/** Called when a channel is forbidden
* @param ci The channel
*/
virtual void OnChanForbidden(ChannelInfo *ci) { }
/** Called when a channel is registered
* @param ci The channel
*/
@@ -737,9 +640,10 @@ class CoreExport Module : public Extensible
/** Called when a user requests info for a channel
* @param source The user requesting info
* @param ci The channel the user is requesting info for
* @param info Data to show the user requesting information
* @param ShowHidden true if we should show the user everything
*/
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, bool ShowHidden) { }
virtual void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool ShowHidden) { }
/** Called on cs_findchan()
* @param chname The name being looked up
@@ -751,14 +655,14 @@ class CoreExport Module : public Extensible
* @param priv The privilege being checked for
* @return EVENT_ALLOW for yes, EVENT_STOP to stop all processing
*/
virtual EventReturn OnCheckPriv(ChanAccess *access, ChannelAccess priv) { return EVENT_CONTINUE; }
virtual EventReturn OnCheckPriv(ChanAccess *access, const Anope::string &priv) { return EVENT_CONTINUE; }
/** Check whether an access group has a privilege
* @param group The group
* @param priv The privilege
* @return MOD_ALLOW to allow, MOD_STOP to stop
*/
virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, ChannelAccess priv) { return EVENT_CONTINUE; }
virtual EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv) { return EVENT_CONTINUE; }
/** Called when a nick is dropped
* @param u The user dropping the nick
@@ -855,9 +759,10 @@ class CoreExport Module : public Extensible
/** Called when a user requests info for a nick
* @param source The user requesting info
* @param na The nick the user is requesting info from
* @param info Data to show the user requesting information
* @param ShowHidden true if we should show the user everything
*/
virtual void OnNickInfo(CommandSource &source, NickAlias *na, bool ShowHidden) { }
virtual void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool ShowHidden) { }
/** Called in findnick()
* Useful to modify the na returned by findnick()
@@ -978,10 +883,10 @@ class CoreExport Module : public Extensible
/** Called when a mode is about to be unlocked
* @param ci The channel the mode is being unlocked from
* @param mode The mode being unlocked
* @param lock The mode lock
* @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to deny the mlock.
*/
virtual EventReturn OnUnMLock(ChannelInfo *ci, ChannelMode *mode, const Anope::string &param) { return EVENT_CONTINUE; }
virtual EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) { return EVENT_CONTINUE; }
/** Called after a module is loaded
* @param u The user loading the module, can be NULL
@@ -1019,6 +924,11 @@ class CoreExport Module : public Extensible
* @param msg The message
*/
virtual void OnPrivmsg(User *u, Channel *c, Anope::string &msg) { }
/** Called when a message is logged
* @param l The log message
*/
virtual void OnLog(Log *l) { }
};
/** Implementation-specific flags which may be set in ModuleManager::Attach()
@@ -1036,7 +946,7 @@ enum Implementation
I_OnNickUpdate,
/* ChanServ */
I_OnChanForbidden, I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd,
I_OnChanSuspend, I_OnChanDrop, I_OnPreChanExpire, I_OnChanExpire, I_OnAccessAdd,
I_OnAccessDel, I_OnAccessClear, I_OnLevelChange, I_OnChanRegistered, I_OnChanUnsuspend, I_OnCreateChan, I_OnDelChan, I_OnChannelCreate,
I_OnChannelDelete, I_OnAkickAdd, I_OnAkickDel, I_OnCheckKick,
I_OnChanInfo, I_OnFindChan, I_OnCheckPriv, I_OnGroupCheckPriv,
@@ -1060,8 +970,7 @@ enum Implementation
I_OnAddXLine, I_OnDelXLine, I_IsServicesOper,
/* Database */
I_OnPostLoadDatabases, I_OnSaveDatabase, I_OnLoadDatabase,
I_OnDatabaseWrite, I_OnDatabaseRead, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata,
I_OnSaveDatabase, I_OnLoadDatabase,
/* Modules */
I_OnModuleLoad, I_OnModuleUnload,
@@ -1072,20 +981,14 @@ enum Implementation
I_OnServerQuit, I_OnTopicUpdated,
I_OnEncrypt, I_OnDecrypt,
I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg,
I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnLog,
I_END
};
class Service;
/** Used to manage modules.
*/
class CoreExport ModuleManager
{
private:
/** A map of service providers
*/
static std::map<Anope::string, Service *> ServiceProviders;
public:
/** Event handler hooks.
* This needs to be public to be used by FOREACH_MOD and friends.
@@ -1096,11 +999,6 @@ class CoreExport ModuleManager
*/
static void CleanupRuntimeDirectory();
/** Load up a list of modules.
* @param module_list The list of modules to load
**/
static void LoadModuleList(std::list<Anope::string> &ModList);
/** Loads a given module.
* @param m the module to load
* @param u the user who loaded it, NULL for auto-load
@@ -1197,29 +1095,6 @@ class CoreExport ModuleManager
*/
static void UnloadAll();
/** Register a service
* @param s The service
* @return true if it was successfully registeed, else false (service name colision)
*/
static bool RegisterService(Service *s);
/** Unregister a service
* @param s The service
* @return true if it was unregistered successfully
*/
static bool UnregisterService(Service *s);
/** Get a service
* @param name The service name
* @return The services, or NULL
*/
static Service *GetService(const Anope::string &name);
/** Get the existing service key names
* @return The keys
*/
static std::vector<Anope::string> GetServiceKeys();
private:
/** Call the module_delete function to safely delete the module
* @param m the module to delete
@@ -1251,13 +1126,19 @@ class CallBack : public Timer
template<typename T>
class service_reference : public dynamic_reference<T>
{
Anope::string type;
Anope::string name;
public:
service_reference(const Anope::string &n) : dynamic_reference<T>(static_cast<T *>(ModuleManager::GetService(n))), name(n)
service_reference(const Anope::string &t, const Anope::string &n) : dynamic_reference<T>(NULL), type(t), name(n)
{
}
inline void operator=(const Anope::string &n)
{
this->name = n;
}
operator bool()
{
if (this->invalid)
@@ -1267,7 +1148,7 @@ class service_reference : public dynamic_reference<T>
}
if (!this->ref)
{
this->ref = static_cast<T *>(ModuleManager::GetService(this->name));
this->ref = static_cast<T *>(Service::FindService(this->type, this->name));
if (this->ref)
this->ref->AddReference(this);
}
+36 -34
View File
@@ -1,6 +1,6 @@
/* OperServ support
*
* (C) 2008-2011 Anope Team
* (C) 2008-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -11,7 +11,7 @@
class XLineManager;
class CoreExport XLine
class CoreExport XLine : public Serializable
{
public:
Anope::string Mask;
@@ -19,39 +19,33 @@ class CoreExport XLine
time_t Created;
time_t Expires;
Anope::string Reason;
XLineManager *manager;
Anope::string UID;
XLine(const Anope::string &mask, const Anope::string &reason = "");
XLine(const Anope::string &mask, const Anope::string &reason = "", const Anope::string &uid = "");
XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason);
XLine(const Anope::string &mask, const Anope::string &by, const time_t expires, const Anope::string &reason, const Anope::string &uid);
Anope::string GetNick() const;
Anope::string GetUser() const;
Anope::string GetHost() const;
sockaddrs GetIP() const;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &data);
};
class CoreExport XLineManager : public Service
{
char type;
protected:
/* List of XLines in this XLineManager */
std::vector<XLine *> XLines;
static std::map<Anope::string, XLine *, ci::less> XLinesByUID;
public:
/* List of XLine managers we check users against in XLineManager::CheckAll */
static std::list<XLineManager *> XLineManagers;
/** Constructor
*/
XLineManager(Module *creator, const Anope::string &name, char t);
/** Destructor
*/
virtual ~XLineManager();
/** The type of xline provided by this service
* @return The type
*/
const char &Type();
/** 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
@@ -71,6 +65,24 @@ class CoreExport XLineManager : public Service
*/
static std::pair<XLineManager *, XLine *> CheckAll(User *u);
/** Generate a unique ID for this XLine
* @return A unique ID
*/
static Anope::string GenerateUID();
/** Constructor
*/
XLineManager(Module *creator, const Anope::string &name, char t);
/** Destructor
*/
virtual ~XLineManager();
/** The type of xline provided by this service
* @return The type
*/
const char &Type();
/** Get the number of XLines in this XLineManager
* @return The number of XLines
*/
@@ -99,25 +111,10 @@ class CoreExport XLineManager : public Service
XLine *GetEntry(unsigned index);
/** Clear the XLine vector
* Note: This does not remove the XLines from the IRCd
*/
void Clear();
/** Add an entry to this XLine Manager
* @param mask The mask of the XLine
* @param creator The creator of the XLine
* @param expires When this should expire
* @param reaosn The reason
* @return A pointer to the XLine
*/
virtual XLine *Add(const Anope::string &mask, const Anope::string &creator, time_t expires, const Anope::string &reason);
private:
/** Delete an XLine, eg, remove it from the IRCd.
* @param x The xline
*/
virtual void Del(XLine *x);
public:
/** Checks if a mask can/should be added to the XLineManager
* @param mask The mask
* @param expires When the mask would expire
@@ -157,6 +154,11 @@ class CoreExport XLineManager : public Service
* @param x The xline
*/
virtual void Send(User *u, XLine *x) = 0;
/** Called to remove an XLine from the IRCd
* @param x The XLine
*/
virtual void SendDel(XLine *x) = 0;
};
#endif // OPER_H
+9 -4
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
* Copyright (C) 2008-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
@@ -15,13 +15,18 @@ class OperType;
struct CoreExport Oper
{
Anope::string name;
OperType *ot;
bool require_oper;
Anope::string password;
Anope::string certfp;
OperType *ot;
bool config;
Oper(const Anope::string &n, const Anope::string &p, const Anope::string &c, OperType *o) :
name(n), password(p), certfp(c), ot(o), config(false) { }
std::vector<Anope::string> hosts;
Anope::string vhost;
Oper(const Anope::string &n, OperType *o) : name(n), ot(o) { this->config = false; }
virtual ~Oper() { }
/** Find an oper block by name
* @param name The name
+800
View File
@@ -0,0 +1,800 @@
/* A portable stdint.h
****************************************************************************
* BSD License:
****************************************************************************
*
* Copyright (c) 2005-2011 Paul Hsieh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************
*
* Version 0.1.12
*
* The ANSI C standard committee, for the C99 standard, specified the
* inclusion of a new standard include file called stdint.h. This is
* a very useful and long desired include file which contains several
* very precise definitions for integer scalar types that is
* critically important for making portable several classes of
* applications including cryptography, hashing, variable length
* integer libraries and so on. But for most developers its likely
* useful just for programming sanity.
*
* The problem is that most compiler vendors have decided not to
* implement the C99 standard, and the next C++ language standard
* (which has a lot more mindshare these days) will be a long time in
* coming and its unknown whether or not it will include stdint.h or
* how much adoption it will have. Either way, it will be a long time
* before all compilers come with a stdint.h and it also does nothing
* for the extremely large number of compilers available today which
* do not include this file, or anything comparable to it.
*
* So that's what this file is all about. Its an attempt to build a
* single universal include file that works on as many platforms as
* possible to deliver what stdint.h is supposed to. A few things
* that should be noted about this file:
*
* 1) It is not guaranteed to be portable and/or present an identical
* interface on all platforms. The extreme variability of the
* ANSI C standard makes this an impossibility right from the
* very get go. Its really only meant to be useful for the vast
* majority of platforms that possess the capability of
* implementing usefully and precisely defined, standard sized
* integer scalars. Systems which are not intrinsically 2s
* complement may produce invalid constants.
*
* 2) There is an unavoidable use of non-reserved symbols.
*
* 3) Other standard include files are invoked.
*
* 4) This file may come in conflict with future platforms that do
* include stdint.h. The hope is that one or the other can be
* used with no real difference.
*
* 5) In the current verison, if your platform can't represent
* int32_t, int16_t and int8_t, it just dumps out with a compiler
* error.
*
* 6) 64 bit integers may or may not be defined. Test for their
* presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
* Note that this is different from the C99 specification which
* requires the existence of 64 bit support in the compiler. If
* this is not defined for your platform, yet it is capable of
* dealing with 64 bits then it is because this file has not yet
* been extended to cover all of your system's capabilities.
*
* 7) (u)intptr_t may or may not be defined. Test for its presence
* with the test: #ifdef PTRDIFF_MAX. If this is not defined
* for your platform, then it is because this file has not yet
* been extended to cover all of your system's capabilities, not
* because its optional.
*
* 8) The following might not been defined even if your platform is
* capable of defining it:
*
* WCHAR_MIN
* WCHAR_MAX
* (u)int64_t
* PTRDIFF_MIN
* PTRDIFF_MAX
* (u)intptr_t
*
* 9) The following have not been defined:
*
* WINT_MIN
* WINT_MAX
*
* 10) The criteria for defining (u)int_least(*)_t isn't clear,
* except for systems which don't have a type that precisely
* defined 8, 16, or 32 bit types (which this include file does
* not support anyways). Default definitions have been given.
*
* 11) The criteria for defining (u)int_fast(*)_t isn't something I
* would trust to any particular compiler vendor or the ANSI C
* committee. It is well known that "compatible systems" are
* commonly created that have very different performance
* characteristics from the systems they are compatible with,
* especially those whose vendors make both the compiler and the
* system. Default definitions have been given, but its strongly
* recommended that users never use these definitions for any
* reason (they do *NOT* deliver any serious guarantee of
* improved performance -- not in this file, nor any vendor's
* stdint.h).
*
* 12) The following macros:
*
* PRINTF_INTMAX_MODIFIER
* PRINTF_INT64_MODIFIER
* PRINTF_INT32_MODIFIER
* PRINTF_INT16_MODIFIER
* PRINTF_LEAST64_MODIFIER
* PRINTF_LEAST32_MODIFIER
* PRINTF_LEAST16_MODIFIER
* PRINTF_INTPTR_MODIFIER
*
* are strings which have been defined as the modifiers required
* for the "d", "u" and "x" printf formats to correctly output
* (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
* (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
* PRINTF_INTPTR_MODIFIER is not defined for some systems which
* provide their own stdint.h. PRINTF_INT64_MODIFIER is not
* defined if INT64_MAX is not defined. These are an extension
* beyond what C99 specifies must be in stdint.h.
*
* In addition, the following macros are defined:
*
* PRINTF_INTMAX_HEX_WIDTH
* PRINTF_INT64_HEX_WIDTH
* PRINTF_INT32_HEX_WIDTH
* PRINTF_INT16_HEX_WIDTH
* PRINTF_INT8_HEX_WIDTH
* PRINTF_INTMAX_DEC_WIDTH
* PRINTF_INT64_DEC_WIDTH
* PRINTF_INT32_DEC_WIDTH
* PRINTF_INT16_DEC_WIDTH
* PRINTF_INT8_DEC_WIDTH
*
* Which specifies the maximum number of characters required to
* print the number of that type in either hexadecimal or decimal.
* These are an extension beyond what C99 specifies must be in
* stdint.h.
*
* Compilers tested (all with 0 warnings at their highest respective
* settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
* bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
* .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
*
* This file should be considered a work in progress. Suggestions for
* improvements, especially those which increase coverage are strongly
* encouraged.
*
* Acknowledgements
*
* The following people have made significant contributions to the
* development and testing of this file:
*
* Chris Howie
* John Steele Scott
* Dave Thorup
* John Dill
*
*/
#include <stddef.h>
#include <limits.h>
#include <signal.h>
/*
* For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
*/
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
#include <stdint.h>
#define _PSTDINT_H_INCLUDED
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER "l"
# endif
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER "h"
# endif
# ifndef PRINTF_INTMAX_MODIFIER
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INT64_HEX_WIDTH
# define PRINTF_INT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_INT32_HEX_WIDTH
# define PRINTF_INT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_INT16_HEX_WIDTH
# define PRINTF_INT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_INT8_HEX_WIDTH
# define PRINTF_INT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_INT64_DEC_WIDTH
# define PRINTF_INT64_DEC_WIDTH "20"
# endif
# ifndef PRINTF_INT32_DEC_WIDTH
# define PRINTF_INT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_INT16_DEC_WIDTH
# define PRINTF_INT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_INT8_DEC_WIDTH
# define PRINTF_INT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
/*
* Something really weird is going on with Open Watcom. Just pull some of
* these duplicated definitions from Open Watcom's stdint.h file for now.
*/
# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
# if !defined (INT64_C)
# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
# endif
# if !defined (UINT64_C)
# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
# endif
# if !defined (INT32_C)
# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
# endif
# if !defined (UINT32_C)
# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
# endif
# if !defined (INT16_C)
# define INT16_C(x) (x)
# endif
# if !defined (UINT16_C)
# define UINT16_C(x) (x)
# endif
# if !defined (INT8_C)
# define INT8_C(x) (x)
# endif
# if !defined (UINT8_C)
# define UINT8_C(x) (x)
# endif
# if !defined (UINT64_MAX)
# define UINT64_MAX 18446744073709551615ULL
# endif
# if !defined (INT64_MAX)
# define INT64_MAX 9223372036854775807LL
# endif
# if !defined (UINT32_MAX)
# define UINT32_MAX 4294967295UL
# endif
# if !defined (INT32_MAX)
# define INT32_MAX 2147483647L
# endif
# if !defined (INTMAX_MAX)
# define INTMAX_MAX INT64_MAX
# endif
# if !defined (INTMAX_MIN)
# define INTMAX_MIN INT64_MIN
# endif
# endif
#endif
#ifndef _PSTDINT_H_INCLUDED
#define _PSTDINT_H_INCLUDED
#ifndef SIZE_MAX
# define SIZE_MAX (~(size_t)0)
#endif
/*
* Deduce the type assignments from limits.h under the assumption that
* integer sizes in bits are powers of 2, and follow the ANSI
* definitions.
*/
#ifndef UINT8_MAX
# define UINT8_MAX 0xff
#endif
#ifndef uint8_t
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
typedef unsigned char uint8_t;
# define UINT8_C(v) ((uint8_t) v)
# else
# error "Platform not supported"
# endif
#endif
#ifndef INT8_MAX
# define INT8_MAX 0x7f
#endif
#ifndef INT8_MIN
# define INT8_MIN INT8_C(0x80)
#endif
#ifndef int8_t
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
typedef signed char int8_t;
# define INT8_C(v) ((int8_t) v)
# else
# error "Platform not supported"
# endif
#endif
#ifndef UINT16_MAX
# define UINT16_MAX 0xffff
#endif
#ifndef uint16_t
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
typedef unsigned int uint16_t;
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER ""
# endif
# define UINT16_C(v) ((uint16_t) (v))
#elif (USHRT_MAX == UINT16_MAX)
typedef unsigned short uint16_t;
# define UINT16_C(v) ((uint16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif
#ifndef INT16_MAX
# define INT16_MAX 0x7fff
#endif
#ifndef INT16_MIN
# define INT16_MIN INT16_C(0x8000)
#endif
#ifndef int16_t
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
typedef signed int int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER ""
# endif
#elif (SHRT_MAX == INT16_MAX)
typedef signed short int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
# define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif
#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffffUL)
#endif
#ifndef uint32_t
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
typedef unsigned long uint32_t;
# define UINT32_C(v) v ## UL
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER "l"
# endif
#elif (UINT_MAX == UINT32_MAX)
typedef unsigned int uint32_t;
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
# define UINT32_C(v) v ## U
#elif (USHRT_MAX == UINT32_MAX)
typedef unsigned short uint32_t;
# define UINT32_C(v) ((unsigned short) (v))
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif
#ifndef INT32_MAX
# define INT32_MAX (0x7fffffffL)
#endif
#ifndef INT32_MIN
# define INT32_MIN INT32_C(0x80000000)
#endif
#ifndef int32_t
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
typedef signed long int32_t;
# define INT32_C(v) v ## L
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER "l"
# endif
#elif (INT_MAX == INT32_MAX)
typedef signed int int32_t;
# define INT32_C(v) v
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
#elif (SHRT_MAX == INT32_MAX)
typedef signed short int32_t;
# define INT32_C(v) ((short) (v))
# ifndef PRINTF_INT32_MODIFIER
# define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif
/*
* The macro stdint_int64_defined is temporarily used to record
* whether or not 64 integer support is available. It must be
* defined for any 64 integer extensions for new platforms that are
* added.
*/
#undef stdint_int64_defined
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
# define stdint_int64_defined
typedef long long int64_t;
typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# endif
#endif
#if !defined (stdint_int64_defined)
# if defined(__GNUC__)
# define stdint_int64_defined
__extension__ typedef long long int64_t;
__extension__ typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
# define stdint_int64_defined
typedef long long int64_t;
typedef unsigned long long uint64_t;
# define UINT64_C(v) v ## ULL
# define INT64_C(v) v ## LL
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "ll"
# endif
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
# define stdint_int64_defined
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# define UINT64_C(v) v ## UI64
# define INT64_C(v) v ## I64
# ifndef PRINTF_INT64_MODIFIER
# define PRINTF_INT64_MODIFIER "I64"
# endif
# endif
#endif
#if !defined (LONG_LONG_MAX) && defined (INT64_C)
# define LONG_LONG_MAX INT64_C (9223372036854775807)
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
#endif
#if !defined (INT64_MAX) && defined (INT64_C)
# define INT64_MAX INT64_C (9223372036854775807)
#endif
#if !defined (INT64_MIN) && defined (INT64_C)
# define INT64_MIN INT64_C (-9223372036854775808)
#endif
#if !defined (UINT64_MAX) && defined (INT64_C)
# define UINT64_MAX UINT64_C (18446744073709551615)
#endif
/*
* Width of hexadecimal for number field.
*/
#ifndef PRINTF_INT64_HEX_WIDTH
# define PRINTF_INT64_HEX_WIDTH "16"
#endif
#ifndef PRINTF_INT32_HEX_WIDTH
# define PRINTF_INT32_HEX_WIDTH "8"
#endif
#ifndef PRINTF_INT16_HEX_WIDTH
# define PRINTF_INT16_HEX_WIDTH "4"
#endif
#ifndef PRINTF_INT8_HEX_WIDTH
# define PRINTF_INT8_HEX_WIDTH "2"
#endif
#ifndef PRINTF_INT64_DEC_WIDTH
# define PRINTF_INT64_DEC_WIDTH "20"
#endif
#ifndef PRINTF_INT32_DEC_WIDTH
# define PRINTF_INT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_INT16_DEC_WIDTH
# define PRINTF_INT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_INT8_DEC_WIDTH
# define PRINTF_INT8_DEC_WIDTH "3"
#endif
/*
* Ok, lets not worry about 128 bit integers for now. Moore's law says
* we don't need to worry about that until about 2040 at which point
* we'll have bigger things to worry about.
*/
#ifdef stdint_int64_defined
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
# define INTMAX_MAX INT64_MAX
# define INTMAX_MIN INT64_MIN
# define UINTMAX_MAX UINT64_MAX
# define UINTMAX_C(v) UINT64_C(v)
# define INTMAX_C(v) INT64_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
#else
typedef int32_t intmax_t;
typedef uint32_t uintmax_t;
# define INTMAX_MAX INT32_MAX
# define UINTMAX_MAX UINT32_MAX
# define UINTMAX_C(v) UINT32_C(v)
# define INTMAX_C(v) INT32_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
# endif
#endif
/*
* Because this file currently only supports platforms which have
* precise powers of 2 as bit sizes for the default integers, the
* least definitions are all trivial. Its possible that a future
* version of this file could have different definitions.
*/
#ifndef stdint_least_defined
typedef int8_t int_least8_t;
typedef uint8_t uint_least8_t;
typedef int16_t int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t int_least32_t;
typedef uint32_t uint_least32_t;
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
# define UINT_LEAST8_MAX UINT8_MAX
# define INT_LEAST8_MAX INT8_MAX
# define UINT_LEAST16_MAX UINT16_MAX
# define INT_LEAST16_MAX INT16_MAX
# define UINT_LEAST32_MAX UINT32_MAX
# define INT_LEAST32_MAX INT32_MAX
# define INT_LEAST8_MIN INT8_MIN
# define INT_LEAST16_MIN INT16_MIN
# define INT_LEAST32_MIN INT32_MIN
# ifdef stdint_int64_defined
typedef int64_t int_least64_t;
typedef uint64_t uint_least64_t;
# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
# define UINT_LEAST64_MAX UINT64_MAX
# define INT_LEAST64_MAX INT64_MAX
# define INT_LEAST64_MIN INT64_MIN
# endif
#endif
#undef stdint_least_defined
/*
* The ANSI C committee pretending to know or specify anything about
* performance is the epitome of misguided arrogance. The mandate of
* this file is to *ONLY* ever support that absolute minimum
* definition of the fast integer types, for compatibility purposes.
* No extensions, and no attempt to suggest what may or may not be a
* faster integer type will ever be made in this file. Developers are
* warned to stay away from these types when using this or any other
* stdint.h.
*/
typedef int_least8_t int_fast8_t;
typedef uint_least8_t uint_fast8_t;
typedef int_least16_t int_fast16_t;
typedef uint_least16_t uint_fast16_t;
typedef int_least32_t int_fast32_t;
typedef uint_least32_t uint_fast32_t;
#define UINT_FAST8_MAX UINT_LEAST8_MAX
#define INT_FAST8_MAX INT_LEAST8_MAX
#define UINT_FAST16_MAX UINT_LEAST16_MAX
#define INT_FAST16_MAX INT_LEAST16_MAX
#define UINT_FAST32_MAX UINT_LEAST32_MAX
#define INT_FAST32_MAX INT_LEAST32_MAX
#define INT_FAST8_MIN INT_LEAST8_MIN
#define INT_FAST16_MIN INT_LEAST16_MIN
#define INT_FAST32_MIN INT_LEAST32_MIN
#ifdef stdint_int64_defined
typedef int_least64_t int_fast64_t;
typedef uint_least64_t uint_fast64_t;
# define UINT_FAST64_MAX UINT_LEAST64_MAX
# define INT_FAST64_MAX INT_LEAST64_MAX
# define INT_FAST64_MIN INT_LEAST64_MIN
#endif
#undef stdint_int64_defined
/*
* Whatever piecemeal, per compiler thing we can do about the wchar_t
* type limits.
*/
#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
# include <wchar.h>
# ifndef WCHAR_MIN
# define WCHAR_MIN 0
# endif
# ifndef WCHAR_MAX
# define WCHAR_MAX ((wchar_t)-1)
# endif
#endif
/*
* Whatever piecemeal, per compiler/platform thing we can do about the
* (u)intptr_t types and limits.
*/
#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
# define STDINT_H_UINTPTR_T_DEFINED
#endif
#ifndef STDINT_H_UINTPTR_T_DEFINED
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
# define stdint_intptr_bits 64
# elif defined (__WATCOMC__) || defined (__TURBOC__)
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
# define stdint_intptr_bits 16
# else
# define stdint_intptr_bits 32
# endif
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
# define stdint_intptr_bits 32
# elif defined (__INTEL_COMPILER)
/* TODO -- what did Intel do about x86-64? */
# endif
# ifdef stdint_intptr_bits
# define stdint_intptr_glue3_i(a,b,c) a##b##c
# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
# ifndef PRINTF_INTPTR_MODIFIER
# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
# endif
# ifndef PTRDIFF_MAX
# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
# endif
# ifndef PTRDIFF_MIN
# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
# endif
# ifndef UINTPTR_MAX
# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
# endif
# ifndef INTPTR_MAX
# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
# endif
# ifndef INTPTR_MIN
# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
# endif
# ifndef INTPTR_C
# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
# endif
# ifndef UINTPTR_C
# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
# endif
typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
# else
/* TODO -- This following is likely wrong for some platforms, and does
nothing for the definition of uintptr_t. */
typedef ptrdiff_t intptr_t;
# endif
# define STDINT_H_UINTPTR_T_DEFINED
#endif
/*
* Assumes sig_atomic_t is signed and we have a 2s complement machine.
*/
#ifndef SIG_ATOMIC_MAX
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
#endif
#endif
#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
/*
* Please compile with the maximum warning settings to make sure macros are not
* defined more than once.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define glue3_aux(x,y,z) x ## y ## z
#define glue3(x,y,z) glue3_aux(x,y,z)
#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0);
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0);
#define DECL(us,bits) glue3(DECL,us,) (bits)
#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits)
int main () {
DECL(I,8)
DECL(U,8)
DECL(I,16)
DECL(U,16)
DECL(I,32)
DECL(U,32)
#ifdef INT64_MAX
DECL(I,64)
DECL(U,64)
#endif
intmax_t imax = INTMAX_C(0);
uintmax_t umax = UINTMAX_C(0);
char str0[256], str1[256];
sprintf (str0, "%d %x\n", 0, ~0);
sprintf (str1, "%d %x\n", i8, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1);
sprintf (str1, "%u %x\n", u8, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1);
sprintf (str1, "%d %x\n", i16, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1);
sprintf (str1, "%u %x\n", u16, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1);
sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1);
sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1);
#ifdef INT64_MAX
sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1);
#endif
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1);
sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1);
TESTUMAX(8);
TESTUMAX(16);
TESTUMAX(32);
#ifdef INT64_MAX
TESTUMAX(64);
#endif
return EXIT_SUCCESS;
}
#endif
+97 -22
View File
@@ -1,6 +1,6 @@
/* Modular support
*
* (C) 2008-2011 Anope Team
* (C) 2008-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -36,8 +36,6 @@ enum ChannelInfoFlag
CI_NO_EXPIRE,
/* Channel memo limit may not be changed */
CI_MEMO_HARDMAX,
/* Send notice to channel on use of OP/DEOP */
CI_OPNOTICE,
/* Stricter control of channel founder status */
CI_SECUREFOUNDER,
/* Sign kicks with the user who did the kick */
@@ -58,10 +56,36 @@ enum ChannelInfoFlag
const Anope::string ChannelInfoFlagStrings[] = {
"BEGIN", "KEEPTOPIC", "SECUREOPS", "PRIVATE", "TOPICLOCK", "RESTRICTED",
"PEACE", "SECURE", "NO_EXPIRE", "MEMO_HARDMAX", "OPNOTICE", "SECUREFOUNDER",
"PEACE", "SECURE", "NO_EXPIRE", "MEMO_HARDMAX", "SECUREFOUNDER",
"SIGNKICK", "SIGNKICK_LEVEL", "SUSPENDED", "PERSIST", ""
};
/** Flags for badwords
*/
enum BadWordType
{
/* Always kicks if the word is said */
BW_ANY,
/* User must way the entire word */
BW_SINGLE,
/* The word has to start with the badword */
BW_START,
/* The word has to end with the badword */
BW_END
};
/* Structure used to contain bad words. */
struct CoreExport BadWord : Serializable
{
ChannelInfo *ci;
Anope::string word;
BadWordType type;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
};
/** Flags for auto kick
*/
enum AutoKickFlag
@@ -73,10 +97,11 @@ enum AutoKickFlag
const Anope::string AutoKickFlagString[] = { "AK_ISNICK", "" };
/* AutoKick data. */
class AutoKick : public Flags<AutoKickFlag>
class CoreExport AutoKick : public Flags<AutoKickFlag>, public Serializable
{
public:
AutoKick() : Flags<AutoKickFlag>(AutoKickFlagString) { }
AutoKick();
ChannelInfo *ci;
/* Only one of these can be in use */
Anope::string mask;
NickCore *nc;
@@ -85,30 +110,60 @@ class AutoKick : public Flags<AutoKickFlag>
Anope::string creator;
time_t addtime;
time_t last_used;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
};
struct ModeLock
struct CoreExport ModeLock : Serializable
{
public:
ChannelInfo *ci;
bool set;
ChannelModeName name;
Anope::string param;
Anope::string setter;
time_t created;
ModeLock(bool s, ChannelModeName n, const Anope::string &p, const Anope::string &se = "", time_t c = Anope::CurTime) : set(s), name(n), param(p), setter(se), created(c) { }
ModeLock(ChannelInfo *ch, bool s, ChannelModeName n, const Anope::string &p, const Anope::string &se = "", time_t c = Anope::CurTime);
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
};
class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, CI_END>
struct CoreExport LogSetting : Serializable
{
ChannelInfo *ci;
/* Our service name of the command */
Anope::string service_name;
/* The name of the client the command is on */
Anope::string command_service;
/* Name of the command to the user, can have spaces */
Anope::string command_name;
Anope::string method, extra;
Anope::string creator;
time_t created;
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
};
class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, CI_END>, public Serializable
{
private:
NickCore *founder; /* Channel founder */
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::map<Anope::string, int16_t> levels;
public:
typedef std::multimap<ChannelModeName, ModeLock> ModeList;
ModeList mode_locks;
std::vector<LogSetting> log_settings;
/** Default constructor
* @param chname The channel name
@@ -135,8 +190,7 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
Anope::string last_topic_setter; /* Setter */
time_t last_topic_time; /* Time */
int16 bantype;
int16 levels[CA_SIZE];
int16_t bantype;
MemoInfo memos;
@@ -145,11 +199,15 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
/* For BotServ */
BotInfo *bi; /* Bot used on this channel */
Flags<BotServFlag> botflags;
int16 ttb[TTB_SIZE]; /* Times to ban for each kicker */
int16_t ttb[TTB_SIZE]; /* Times to ban for each kicker */
int16 capsmin, capspercent; /* For CAPS kicker */
int16 floodlines, floodsecs; /* For FLOOD kicker */
int16 repeattimes; /* For REPEAT kicker */
int16_t capsmin, capspercent; /* For CAPS kicker */
int16_t floodlines, floodsecs; /* For FLOOD kicker */
int16_t repeattimes; /* For REPEAT kicker */
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
/** Change the founder of the channek
* @params nc The new founder
@@ -278,11 +336,6 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
*/
void ClearBadWords();
/** 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 LoadMLock();
/** Check if a mode is mlocked
* @param mode The mode
* @param An optional param
@@ -331,7 +384,7 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
ModeLock *GetMLock(ChannelModeName mname, const Anope::string &param = "");
/** Get the current mode locks as a string
* @param complete True to show mlock parameters aswell
* @param complete True to show mlock parameters aswell
* @return A string of mode locks, eg: +nrt
*/
Anope::string GetMLockAsString(bool complete) const;
@@ -347,11 +400,33 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag,
* the new topic in the ChannelInfo
*/
void CheckTopic();
/** Restore the channel topic, used on channel creation when not syncing with the uplink
* and after uplink sync
*/
void RestoreTopic();
/** Get the level for a privilege
* @param priv The privilege name
* @return the level
* @throws CoreException if priv is not a valid privilege
*/
int16_t GetLevel(const Anope::string &priv);
/** Set the level for a privilege
* @param priv The privilege priv
* @param level The new level
*/
void SetLevel(const Anope::string &priv, int16_t level);
/** Remove a privilege from the channel
* @param priv The privilege
*/
void RemoveLevel(const Anope::string &priv);
/** Clear all privileges from the channel
*/
void ClearLevels();
};
/** A timer used to keep the BotServ bot/ChanServ in the channel
+159
View File
@@ -0,0 +1,159 @@
#ifndef SERIALIZE_H
#define SERIALIZE_H
namespace Serialize
{
enum DataType
{
DT_TEXT,
DT_INT
};
class stringstream : public std::stringstream
{
private:
DataType type;
bool key;
unsigned _max;
public:
stringstream() : std::stringstream(), type(DT_TEXT), key(false), _max(0) { }
stringstream(const stringstream &ss) : std::stringstream(ss.str()), type(DT_TEXT), key(false), _max(0) { }
Anope::string astr() const { return this->str(); }
template<typename T> std::istream &operator>>(T &val)
{
std::istringstream is(this->str());
is >> val;
return *this;
}
std::istream &operator>>(Anope::string &val)
{
val = this->str();
return *this;
}
stringstream &setType(DataType t)
{
this->type = t;
return *this;
}
DataType getType() const
{
return this->type;
}
stringstream &setKey()
{
this->key = true;
return *this;
}
bool getKey() const
{
return this->key;
}
stringstream &setMax(unsigned m)
{
this->_max = m;
return *this;
}
unsigned getMax() const
{
return this->_max;
}
};
}
extern void RegisterTypes();
class CoreExport Serializable
{
private:
static std::list<Serializable *> *serizliable_items;
std::list<Serializable *>::iterator s_iter;
protected:
Serializable()
{
if (serizliable_items == NULL)
serizliable_items = new std::list<Serializable *>();
serizliable_items->push_front(this);
this->s_iter = serizliable_items->begin();
}
Serializable(const Serializable &)
{
serizliable_items->push_front(this);
this->s_iter = serizliable_items->begin();
}
virtual ~Serializable()
{
serizliable_items->erase(this->s_iter);
}
Serializable &operator=(const Serializable &)
{
return *this;
}
public:
typedef std::map<Anope::string, Serialize::stringstream> serialized_data;
virtual Anope::string serialize_name() const = 0;
virtual serialized_data serialize() = 0;
static const std::list<Serializable *> &GetItems()
{
return *serizliable_items;
}
};
class CoreExport SerializeType
{
typedef void (*unserialize_func)(Serializable::serialized_data &);
static std::vector<Anope::string> type_order;
static Anope::map<SerializeType *> types;
Anope::string name;
unserialize_func unserialize;
public:
SerializeType(const Anope::string &n, unserialize_func f) : name(n), unserialize(f)
{
type_order.push_back(this->name);
types[this->name] = this;
}
~SerializeType()
{
std::vector<Anope::string>::iterator it = std::find(type_order.begin(), type_order.end(), this->name);
if (it != type_order.end())
type_order.erase(it);
types.erase(this->name);
}
const Anope::string &GetName()
{
return this->name;
}
void Create(Serializable::serialized_data &data)
{
this->unserialize(data);
}
static SerializeType *Find(const Anope::string &name)
{
Anope::map<SerializeType *>::iterator it = types.find(name);
if (it != types.end())
return it->second;
return NULL;
}
static const std::vector<Anope::string> &GetTypeOrder()
{
return type_order;
}
};
#endif // SERIALIZE_H
+7 -23
View File
@@ -9,29 +9,7 @@ extern CoreExport void do_server(const Anope::string &source, const Anope::strin
extern CoreExport const Anope::string ts6_uid_retrieve();
extern CoreExport const Anope::string ts6_sid_retrieve();
/* Types of capab
*/
enum CapabType
{
CAPAB_BEGIN,
CAPAB_NOQUIT,
CAPAB_TSMODE,
CAPAB_UNCONNECT,
CAPAB_QS,
CAPAB_END
};
/* CAPAB stuffs */
struct CapabInfo
{
Anope::string Token;
CapabType Flag;
};
extern CoreExport Flags<CapabType, CAPAB_END> Capab;
extern CoreExport CapabInfo Capab_Info[];
extern CoreExport std::set<Anope::string> Capab;
/** Flags set on servers
*/
@@ -152,6 +130,12 @@ class CoreExport Server : public Flags<ServerFlag>
*/
bool IsULined() const;
/** Send a message to alll users on this server
* @param source The source of the message
* @param message The message
*/
void Notice(BotInfo *source, const Anope::string &message);
/** 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
+138 -139
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -20,19 +20,16 @@
#define BUFSIZE 1024
/* Some SUN fixs */
#ifdef __sun
# ifndef INADDR_NONE
# define INADDR_NONE (-1)
# endif
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>
#include <string.h>
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#include <signal.h>
#include <time.h>
#include <errno.h>
@@ -42,6 +39,7 @@
#include <sys/types.h>
#include <fcntl.h>
#include <typeinfo>
#include <ctype.h>
#if GETTEXT_FOUND
# include <libintl.h>
@@ -56,11 +54,12 @@
# include <arpa/inet.h>
# include <sys/socket.h>
# include <sys/time.h>
# include <sys/wait.h>
# include <dirent.h>
# include <pthread.h>
# define DllExport
# define CoreExport
# define MARK_DEPRECATED __attribute((deprecated))
# define DeleteFile unlink
#else
# include "anope_windows.h"
#endif
@@ -72,33 +71,6 @@
# define FORMAT(type, fmt, start)
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef _AIX
/* Some AIX boxes seem to have bogus includes that don't have these
* prototypes. */
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);
# undef FD_ZERO
# define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
#endif /* _AIX */
/* Alias stricmp/strnicmp to strcasecmp/strncasecmp if we have the latter
* but not the former. */
#if !HAVE_STRICMP && HAVE_STRCASECMP
# define stricmp strcasecmp
# define strnicmp strncasecmp
#endif
/* We have our own versions of toupper()/tolower(). */
#include <ctype.h>
#undef tolower
#undef toupper
#define tolower tolower_
#define toupper toupper_
/** 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 AnopeInit and AnopeFini functions.
@@ -112,12 +84,6 @@ extern int strncasecmp(const char *, const char *, size_t);
} \
BOOLEAN WINAPI DllMain(HINSTANCE, DWORD nReason, LPVOID) \
{ \
switch (nReason) \
{ \
case DLL_PROCESS_ATTACH: \
case DLL_PROCESS_DETACH: \
break; \
} \
return TRUE; \
} \
extern "C" DllExport void AnopeFini(x *); \
@@ -225,37 +191,6 @@ class ModuleException : public CoreException
virtual ~ModuleException() throw() { }
};
class DatabaseException : public CoreException
{
public:
/** This constructor can be used to specify an error message before throwing.
* @param mmessage The exception
*/
DatabaseException(const Anope::string &message) : CoreException(message, "A database module") { }
/** Destructor
* @throws Nothing
*/
virtual ~DatabaseException() throw() { }
};
class Signal
{
static std::vector<Signal *> SignalHandlers;
static void SignalHandler(int signal);
struct sigaction action, old;
sig_atomic_t called;
public:
static void Process();
int signal;
Signal(int s);
~Signal();
virtual void OnSignal() = 0;
};
/** Debug cast to be used instead of dynamic_cast, this uses dynamic_cast
* for debug builds and static_cast on releass builds to speed up the program
* because dynamic_cast relies on RTTI.
@@ -327,7 +262,29 @@ template<typename T, size_t Size = 32> class Flags
Flag_Values.reset();
}
std::vector<Anope::string> ToString()
Anope::string ToString()
{
std::vector<Anope::string> v = ToVector();
Anope::string flag_buf;
for (unsigned i = 0; i < v.size(); ++i)
flag_buf += v[i] + " ";
flag_buf.trim();
return flag_buf;
}
void FromString(const Anope::string &str)
{
spacesepstream sep(str);
Anope::string buf;
std::vector<Anope::string> v;
while (sep.GetToken(buf))
v.push_back(buf);
FromVector(v);
}
std::vector<Anope::string> ToVector()
{
std::vector<Anope::string> ret;
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
@@ -336,8 +293,10 @@ template<typename T, size_t Size = 32> class Flags
return ret;
}
void FromString(const std::vector<Anope::string> &strings)
void FromVector(const std::vector<Anope::string> &strings)
{
this->ClearFlags();
for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i)
for (unsigned j = 0; j < strings.size(); ++j)
if (this->Flag_Strings[i] == strings[j])
@@ -349,16 +308,62 @@ class Module;
class CoreExport Service : public Base
{
static Anope::map<Anope::map<Service *> > services;
public:
static Service *FindService(const Anope::string &t, const Anope::string &n)
{
Anope::map<Anope::map<Service *> >::iterator it = services.find(t);
if (it != services.end())
{
Anope::map<Service *>::iterator it2 = it->second.find(n);
if (it2 != it->second.end())
return it2->second;
}
return NULL;
}
static std::vector<Anope::string> GetServiceKeys(const Anope::string &t)
{
std::vector<Anope::string> keys;
Anope::map<Anope::map<Service *> >::iterator it = services.find(t);
if (it != services.end())
for (Anope::map<Service *>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
keys.push_back(it2->first);
return keys;
}
Module *owner;
Anope::string type;
Anope::string name;
Service(Module *o, const Anope::string &n);
Service(Module *o, const Anope::string &t, const Anope::string &n) : owner(o), type(t), name(n)
{
this->Register();
}
virtual ~Service();
virtual ~Service()
{
this->Unregister();
}
void Register()
{
Anope::map<Service *> &smap = services[this->type];
if (smap.find(this->name) != smap.end())
throw ModuleException("Service " + this->type + " with name " + this->name + " already exists");
smap[this->name] = this;
}
void Unregister()
{
Anope::map<Service *> &smap = services[this->type];
smap.erase(this->name);
if (smap.empty())
services.erase(this->type);
}
};
#include "sockets.h"
#include "socketengine.h"
#include "extensible.h"
@@ -367,6 +372,21 @@ class CoreExport Service : public Base
/*************************************************************************/
class Signal : public Pipe
{
static std::vector<Signal *> SignalHandlers;
static void SignalHandler(int signal);
struct sigaction action, old;
public:
int signal;
Signal(int s);
~Signal();
virtual void OnNotify() = 0;
};
class ConvertException : public CoreException
{
public:
@@ -440,6 +460,7 @@ class Entry;
#include "threadengine.h"
#include "opertype.h"
#include "modes.h"
#include "serialize.h"
/*************************************************************************/
@@ -489,10 +510,16 @@ const Anope::string MemoFlagStrings[] = {
/* Memo info structures. Since both nicknames and channels can have memos,
* we encapsulate memo data in a MemoList to make it easier to handle. */
class CoreExport Memo : public Flags<MemoFlag>
class CoreExport Memo : public Flags<MemoFlag>, public Serializable
{
public:
Memo();
Memo();
Anope::string serialize_name() const;
serialized_data serialize();
static void unserialize(serialized_data &);
Anope::string owner;
time_t time; /* When it was sent */
Anope::string sender;
Anope::string text;
@@ -500,7 +527,7 @@ class CoreExport Memo : public Flags<MemoFlag>
struct CoreExport MemoInfo
{
int16 memomax;
int16_t memomax;
std::vector<Memo *> memos;
std::vector<Anope::string> ignores;
@@ -517,15 +544,7 @@ struct Session
unsigned hits; /* Number of subsequent kills for a host */
};
struct Exception
{
Anope::string mask; /* Hosts to which this exception applies */
unsigned limit; /* Session limit for exception */
Anope::string who; /* Nick of person who added the exception */
Anope::string reason; /* Reason for exception's addition */
time_t time; /* When this exception was added */
time_t expires; /* Time when it expires. 0 == no expiry */
};
struct Exception;
/*************************************************************************/
@@ -573,28 +592,7 @@ class CoreExport HostInfo
/** Retrieve when the vhost was crated
* @return the time it was created
*/
const time_t GetTime() const;
};
/** Flags for badwords
*/
enum BadWordType
{
/* Always kicks if the word is said */
BW_ANY,
/* User must way the entire word */
BW_SINGLE,
/* The word has to start with the badword */
BW_START,
/* The word has to end with the badword */
BW_END
};
/* Structure used to contain bad words. */
struct BadWord
{
Anope::string word;
BadWordType type;
time_t GetTime() const;
};
/* BotServ SET flags */
@@ -631,12 +629,6 @@ enum BotServFlag
BS_KICK_ITALICS,
/* BotServ kicks for amsgs */
BS_KICK_AMSGS,
/* Send fantasy replies back to the channel via PRIVMSG */
BS_MSG_PRIVMSG,
/* Send fantasy replies back to the channel via NOTICE */
BS_MSG_NOTICE,
/* Send fantasy replies back to the channel via NOTICE to ops */
BS_MSG_NOTICEOPS,
BS_END
};
@@ -772,7 +764,6 @@ class CoreExport IRCDProto
virtual void SendModeInternal(const BotInfo *, const Channel *, const Anope::string &) = 0;
virtual void SendModeInternal(const BotInfo *, const User *, const Anope::string &) = 0;
virtual void SendKickInternal(const BotInfo *, const Channel *, const User *, const Anope::string &) = 0;
virtual void SendNoticeChanopsInternal(const BotInfo *bi, const Channel *, const Anope::string &) = 0;
virtual void SendMessageInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf);
virtual void SendNoticeInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &msg);
virtual void SendPrivmsgInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf);
@@ -794,7 +785,6 @@ class CoreExport IRCDProto
virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...);
virtual void SendClientIntroduction(const User *u) = 0;
virtual void SendKick(const BotInfo *bi, const Channel *chan, const User *user, const char *fmt, ...);
virtual void SendNoticeChanops(const BotInfo *bi, const Channel *dest, const char *fmt, ...);
virtual void SendMessage(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendAction(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
@@ -811,7 +801,7 @@ class CoreExport IRCDProto
virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...);
virtual void SendGlobops(const BotInfo *source, const char *fmt, ...);
virtual void SendSQLine(User *, const XLine *x) { }
virtual void SendSquit(const Anope::string &servname, const Anope::string &message);
virtual void SendSquit(Server *, const Anope::string &message);
virtual void SendSVSO(const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendChangeBotNick(const BotInfo *bi, const Anope::string &newnick);
virtual void SendForceNickChange(const User *u, const Anope::string &newnick, time_t when);
@@ -823,7 +813,6 @@ class CoreExport IRCDProto
virtual void SendSZLineDel(const XLine *) { }
virtual void SendSZLine(User *u, const XLine *) { }
virtual void SendSGLine(User *, const XLine *) { }
virtual void SendUnregisteredNick(const User *) { }
virtual void SendCTCP(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...);
virtual void SendSVSJoin(const Anope::string &, const Anope::string &, const Anope::string &, const Anope::string &) { }
virtual void SendSWhois(const Anope::string &, const Anope::string &, const Anope::string &) { }
@@ -833,23 +822,8 @@ class CoreExport IRCDProto
virtual bool IsNickValid(const Anope::string &) { return true; }
virtual bool IsChannelValid(const Anope::string &);
virtual void SendNumeric(const Anope::string &source, int numeric, const Anope::string &dest, const char *fmt, ...);
/** Sends a message logging a user into an account, where ircds support such a feature.
* @param u The user logging in
* @param account The account the user is logging into
*/
virtual void SendAccountLogin(const User *u, const NickCore *account) { }
/** Sends a message logging a user out of an account, where ircds support such a feature.
* @param u The user logging out
* @param account The account the user is logging out of
*/
virtual void SendAccountLogout(const User *u, const NickCore *account) { }
/** Set a users auto identification token
* @param u The user
*/
virtual void SetAutoIdentificationToken(User *u) { }
virtual void SendLogin(User *u) = 0;
virtual void SendLogout(User *u) = 0;
/** Send a channel creation message to the uplink.
* On most TS6 IRCds this is a SJOIN with no nick
@@ -950,4 +924,29 @@ class CoreExport NumberList
virtual bool InvalidRange(const Anope::string &list);
};
class CoreExport ListFormatter
{
public:
typedef std::map<Anope::string, Anope::string> ListEntry;
private:
std::vector<Anope::string> columns;
std::vector<ListEntry> entries;
public:
ListFormatter &addColumn(const Anope::string &name);
void addEntry(const ListEntry &entry);
bool isEmpty() const;
void Process(std::vector<Anope::string> &);
};
class CoreExport InfoFormatter
{
User *user;
std::vector<std::pair<Anope::string, Anope::string> > replies;
unsigned longest;
public:
InfoFormatter(User *u);
void Process(std::vector<Anope::string> &);
Anope::string &operator[](const Anope::string &key);
};
#endif /* SERVICES_H */
+1 -1
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+104 -73
View File
@@ -1,6 +1,6 @@
/*
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -16,12 +16,6 @@
#define NET_BUFSIZE 65535
#ifdef _WIN32
# define CloseSocket closesocket
#else
# define CloseSocket close
#endif
/** A sockaddr union used to combine IPv4 and IPv6 sockaddrs
*/
union CoreExport sockaddrs
@@ -106,22 +100,17 @@ class SocketException : public CoreException
virtual ~SocketException() throw() { }
};
enum SocketType
{
SOCKTYPE_BASE,
SOCKTYPE_BUFFERED,
SOCKTYPE_CONNECTION,
SOCKTYPE_CLIENT,
SOCKTYPE_LISTEN
};
enum SocketFlag
{
SF_DEAD,
SF_WRITABLE
SF_WRITABLE,
SF_CONNECTING,
SF_CONNECTED,
SF_ACCEPTING,
SF_ACCEPTED
};
static const Anope::string SocketFlagStrings[] = { "SF_DEAD", "SF_WRITABLE", "" };
static const Anope::string SocketFlagStrings[] = { "SF_DEAD", "SF_WRITABLE", "SF_CONNECTING", "SF_CONNECTED", "SF_ACCEPTING", "SF_ACCEPTED", "" };
class Socket;
class ClientSocket;
@@ -140,11 +129,12 @@ class CoreExport SocketIO
virtual int Recv(Socket *s, char *buf, size_t sz);
/** Write something to the socket
* @param s The socket
* @param buf What to write
* @return Number of bytes written
* @param s The socket
* @param buf The data to write
* @param size The length of the data
*/
virtual int Send(Socket *s, const Anope::string &buf);
virtual int Send(Socket *s, const char *buf, size_t sz);
int Send(Socket *s, const Anope::string &buf);
/** Accept a connection from a socket
* @param s The socket
@@ -152,11 +142,11 @@ class CoreExport SocketIO
*/
virtual ClientSocket *Accept(ListenSocket *s);
/** Check if a connection has been accepted
* @param s The client socket
* @return -1 on error, 0 to wait, 1 on success
/** Finished accepting a connection from a socket
* @param s The socket
* @return SF_ACCEPTED if accepted, SF_ACCEPTING if still in process, SF_DEAD on error
*/
virtual int Accepted(ClientSocket *cs);
virtual SocketFlag FinishAccept(ClientSocket *cs);
/** Bind a socket
* @param s The socket
@@ -172,18 +162,18 @@ class CoreExport SocketIO
*/
virtual void Connect(ConnectionSocket *s, const Anope::string &target, int port);
/** Check if this socket is connected
/** Called to potentially finish a pending connection
* @param s The socket
* @return -1 for error, 0 for wait, 1 for connected
* @return SF_CONNECTED on success, SF_CONNECTING if still pending, and SF_DEAD on error.
*/
virtual int Connected(ConnectionSocket *s);
virtual SocketFlag FinishConnect(ConnectionSocket *s);
/** Called when the socket is destructing
*/
virtual void Destroy() { }
};
class CoreExport Socket : public Flags<SocketFlag, 2>
class CoreExport Socket : public Flags<SocketFlag>
{
protected:
/* Socket FD */
@@ -198,19 +188,16 @@ class CoreExport Socket : public Flags<SocketFlag, 2>
/* I/O functions used for this socket */
SocketIO *IO;
/* Type this socket is */
SocketType Type;
/** Empty constructor, used for things such as the pipe socket
/** Empty constructor, should not be called.
*/
Socket();
/** Default constructor
* @param sock The socket to use, 0 if we need to create our own
* @param sock The socket to use, -1 if we need to create our own
* @param ipv6 true if using ipv6
* @param type The socket type, defaults to SOCK_STREAM
*/
Socket(int sock, bool ipv6, int type = SOCK_STREAM);
Socket(int sock, bool ipv6 = false, int type = SOCK_STREAM);
/** Default destructor
*/
@@ -242,6 +229,11 @@ class CoreExport Socket : public Flags<SocketFlag, 2>
*/
void Bind(const Anope::string &ip, int port = 0);
/** Called when there either is a read or write event.
* @return true to continue to call ProcessRead/ProcessWrite, false to not continue
*/
virtual bool Process();
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
@@ -258,7 +250,7 @@ class CoreExport Socket : public Flags<SocketFlag, 2>
virtual void ProcessError();
};
class CoreExport BufferedSocket : public Socket
class CoreExport BufferedSocket : public virtual Socket
{
protected:
/* Things to be written to the socket */
@@ -269,17 +261,10 @@ class CoreExport BufferedSocket : public Socket
int RecvLen;
public:
/** Blank constructor
/** Constructor
*/
BufferedSocket();
/** Constructor
* @param fd FD to use
* @param ipv6 true for ipv6
* @param type socket type, defaults to SOCK_STREAM
*/
BufferedSocket(int fd, bool ipv6, int type = SOCK_STREAM);
/** Default destructor
*/
virtual ~BufferedSocket();
@@ -317,6 +302,52 @@ class CoreExport BufferedSocket : public Socket
int WriteBufferLen() const;
};
class CoreExport BinarySocket : public virtual Socket
{
struct DataBlock
{
char *buf;
size_t len;
DataBlock(const char *b, size_t l);
~DataBlock();
};
std::deque<DataBlock *> WriteBuffer;
public:
/** Constructor
*/
BinarySocket();
/** Default destructor
*/
virtual ~BinarySocket();
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
*/
bool ProcessRead();
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
bool ProcessWrite();
/** Write data to the socket
* @param buffer The data to write
* @param l The length of the data
*/
void Write(const char *buffer, size_t l);
/** Called with data from the socket
* @param buffer The data
* @param l The length of buffer
* @return true to continue reading, false to drop the socket
*/
virtual bool Read(const char *buffer, size_t l);
};
class CoreExport ListenSocket : public Socket
{
public:
@@ -341,22 +372,18 @@ class CoreExport ListenSocket : public Socket
* @param addr The sockaddr for where the connection came from
* @return The new socket
*/
virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr);
virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr) = 0;
};
class CoreExport ConnectionSocket : public BufferedSocket
class CoreExport ConnectionSocket : public virtual Socket
{
public:
/* Sockaddrs for connection ip/port */
sockaddrs conaddr;
/* True if connected */
bool connected;
/** Constructor
* @param ipv6 true to use IPv6
* @param type The socket type, defaults to SOCK_STREAM
*/
ConnectionSocket(bool ipv6 = false, int type = SOCK_STREAM);
ConnectionSocket();
/** Connect the socket
* @param TargetHost The target host to connect to
@@ -364,15 +391,11 @@ class CoreExport ConnectionSocket : public BufferedSocket
*/
void Connect(const Anope::string &TargetHost, int Port);
/** Called when there is something to be received for this socket
* @return true on success, false to drop this socket
/** Called when there either is a read or write event.
* Used to determine whether or not this socket is connected yet.
* @return true to continue to call ProcessRead/ProcessWrite, false to not continue
*/
bool ProcessRead();
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
*/
bool ProcessWrite();
bool Process();
/** Called when there is an error for this socket
* @return true on success, false to drop this socket
@@ -389,7 +412,7 @@ class CoreExport ConnectionSocket : public BufferedSocket
virtual void OnError(const Anope::string &error);
};
class CoreExport ClientSocket : public BufferedSocket
class CoreExport ClientSocket : public virtual Socket
{
public:
/* Listen socket this connection came from */
@@ -399,23 +422,31 @@ class CoreExport ClientSocket : public BufferedSocket
/** Constructor
* @param ls Listen socket this connection is from
* @param fd New FD for this socket
* @param addr Address the connection came from
*/
ClientSocket(ListenSocket *ls, int fd, const sockaddrs &addr);
ClientSocket(ListenSocket *ls, const sockaddrs &addr);
/** Called when there is something to be received for this socket
/** Called when there either is a read or write event.
* Used to determine whether or not this socket is connected yet.
* @return true to continue to call ProcessRead/ProcessWrite, false to not continue
*/
bool Process();
/** Called when there is an error for this socket
* @return true on success, false to drop this socket
*/
bool ProcessRead();
void ProcessError();
/** Called when the socket is ready to be written to
* @return true on success, false to drop this socket
/** Called when a client has been accepted() successfully.
*/
bool ProcessWrite();
virtual void OnAccept();
/** Called when there was an error accepting the client
*/
virtual void OnError(const Anope::string &error);
};
class CoreExport Pipe : public BufferedSocket
class CoreExport Pipe : public Socket
{
public:
/** The FD of the write pipe (if this isn't evenfd)
@@ -427,14 +458,14 @@ class CoreExport Pipe : public BufferedSocket
*/
Pipe();
/** Destructor
*/
~Pipe();
/** Called when data is to be read
*/
bool ProcessRead();
/** Function that calls OnNotify
*/
bool Read(const Anope::string &);
/** Called when this pipe needs to be woken up
*/
void Notify();
+9 -77
View File
@@ -4,7 +4,7 @@
#cmakedefine DEBUG_BUILD
#cmakedefine DEFUMASK @DEFUMASK@
#cmakedefine HAVE_SYS_TYPES_H 1
#cmakedefine HAVE_CSTDINT 1
#cmakedefine HAVE_STDINT_H 1
#cmakedefine HAVE_STDDEF_H 1
#cmakedefine HAVE_SETGRENT 1
@@ -18,87 +18,19 @@
#cmakedefine GETTEXT_FOUND 1
#cmakedefine RUNGROUP "@RUNGROUP@"
#cmakedefine HAVE_UINT8_T 1
#cmakedefine HAVE_U_INT8_T 1
#cmakedefine HAVE_INT16_T 1
#cmakedefine HAVE_UINT16_T 1
#cmakedefine HAVE_U_INT16_T 1
#cmakedefine HAVE_INT32_T 1
#cmakedefine HAVE_UINT32_T 1
#cmakedefine HAVE_U_INT32_T 1
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#ifdef HAVE_CSTDINT
# include <cstdint>
#else
# ifdef HAVE_STDINT_H
# include <stdint.h>
# else
# include "pstdint.h"
# endif
#endif
#ifdef HAVE_STDDEF_H
# include <stddef.h>
#endif
#ifdef HAVE_UINT8_T
typedef uint8_t uint8;
#else
# ifdef HAVE_U_INT8_T
typedef u_int8_t uint8;
# else
# ifdef _WIN32
typedef unsigned __int8 uint8;
# else
typedef unsigned short uint8;
# endif
# endif
#endif
#ifdef HAVE_INT16_T
typedef int16_t int16;
#else
# ifdef _WIN32
typedef signed __int16 int16;
# else
typedef int int16;
# endif
#endif
#ifdef HAVE_UINT16_T
typedef uint16_t uint16;
#else
# ifdef HAVE_U_INT16_T
typedef u_int16_t uint16;
# else
# ifdef _WIN32
typedef unsigned __int16 uint16;
# else
typedef unsigned int uint16;
# endif
# endif
#endif
#ifdef HAVE_INT32_T
typedef int32_t int32;
#else
# ifdef _WIN32
typedef signed __int32 int32;
# else
typedef long int32;
# endif
#endif
#ifdef HAVE_UINT32_T
typedef uint32_t uint32;
#else
# ifdef HAVE_U_INT32_T
typedef u_int32_t uint32;
# else
# ifdef _WIN32
typedef unsigned __int32 uint32;
# else
typedef unsigned long uint32;
# endif
# endif
#endif
#ifdef _WIN32
# define popen _popen
# define pclose _pclose
+14 -44
View File
@@ -1,47 +1,9 @@
#ifndef THREADENGINE_H
#define THREADENGINE_H
#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 CoreExport ThreadEngine
{
public:
/* Vector of threads */
std::vector<Thread *> threads;
/** Threadengines constructor
*/
ThreadEngine();
/** Threadengines destructor
*/
~ThreadEngine();
/** Start a new thread
* @param thread A pointer to a newley allocated thread
*/
void Start(Thread *thread);
/** Check for finished threads
*/
void Process();
};
class CoreExport Thread : public Extensible
class CoreExport Thread : public Pipe, public Extensible
{
private:
/* Set to true to tell the thread to finish and we are waiting for it */
@@ -49,7 +11,7 @@ class CoreExport Thread : public Extensible
public:
/* Handle for this thread */
ThreadHandle Handle;
pthread_t Handle;
/** Threads constructor
*/
@@ -71,21 +33,29 @@ class CoreExport Thread : public Extensible
*/
void Exit();
/** Launch the thread
*/
void Start();
/** 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
/** Called when this thread should be joined to
*/
virtual void Run();
void OnNotify();
/** Called when the thread is run.
*/
virtual void Run() = 0;
};
class CoreExport Mutex
{
protected:
/* A mutex, used to keep threads in sync */
MutexHandle mutex;
pthread_mutex_t mutex;
public:
/** Constructor
@@ -115,7 +85,7 @@ class CoreExport Condition : public Mutex
{
private:
/* A condition */
CondHandle cond;
pthread_cond_t cond;
public:
/** Constructor
+1 -1
View File
@@ -1,6 +1,6 @@
/* Timer include stuff.
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2011 Robin Burchell <w00t@inspircd.org>
* Copyright (C) 2008-2011 Anope Team <team@anope.org>
* Copyright (C) 2008-2012 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/* Build bumper
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
+3742 -4528
View File
File diff suppressed because it is too large Load Diff
+3817 -4699
View File
File diff suppressed because it is too large Load Diff
+4815 -9659
View File
File diff suppressed because it is too large Load Diff
+3330 -4098
View File
File diff suppressed because it is too large Load Diff
+4362 -5275
View File
File diff suppressed because it is too large Load Diff
+4429 -5423
View File
File diff suppressed because it is too large Load Diff
+3642 -4457
View File
File diff suppressed because it is too large Load Diff
+3307 -4067
View File
File diff suppressed because it is too large Load Diff
+4531 -5438
View File
File diff suppressed because it is too large Load Diff
+4123 -4986
View File
File diff suppressed because it is too large Load Diff
+4908 -10826
View File
File diff suppressed because it is too large Load Diff
+4125 -5127
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -14,7 +14,7 @@ cd -
for f in *.po
do
msgmerge -E -v -s -U $f `echo $f | cut -d'.' -f1`.pot
msgmerge -v -s -U $f `echo $f | cut -d'.' -f1`.pot
done
rm -f *~
+2
View File
@@ -85,6 +85,8 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS})
if(WIN32)
target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES})
set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}")
else(WIN32)
target_link_libraries(${SO} ${PROGRAM_NAME} ${TEMP_DEPENDENCIES})
endif(WIN32)
# Set the module to be installed to the module directory under the data directory
install(TARGETS ${SO}
+5 -7
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -49,7 +49,7 @@ class CommandBSAssign : public Command
return;
}
if (ci->botflags.HasFlag(BS_NOBOT) || (!ci->AccessFor(u).HasPriv(CA_ASSIGN) && !u->HasPriv("botserv/administration")))
if (ci->botflags.HasFlag(BS_NOBOT) || (!ci->AccessFor(u).HasPriv("ASSIGN") && !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
@@ -67,7 +67,7 @@ class CommandBSAssign : public Command
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
bool override = !ci->AccessFor(u).HasPriv("ASSIGN");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << bi->nick;
bi->Assign(u, ci);
@@ -111,7 +111,7 @@ class CommandBSUnassign : public Command
return;
}
if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_ASSIGN))
if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv("ASSIGN"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -129,7 +129,7 @@ class CommandBSUnassign : public Command
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_ASSIGN);
bool override = !ci->AccessFor(u).HasPriv("ASSIGN");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << ci->bi->nick;
ci->bi->UnAssign(u, ci);
@@ -160,8 +160,6 @@ class BSAssign : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsassign);
ModuleManager::RegisterService(&commandbsunassign);
}
};
+61 -66
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -13,42 +13,6 @@
#include "module.h"
class BadwordsListCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
BadwordsListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &list) : NumberList(list, false), source(_source), ci(_ci), SentHeader(false)
{
}
~BadwordsListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetBadWordCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), ci->name.c_str());
}
DoList(source, Number - 1, ci->GetBadWord(Number - 1));
}
static void DoList(CommandSource &source, unsigned Number, BadWord *bw)
{
source.Reply(_(" %3d %-30s %s"), 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
{
@@ -60,7 +24,7 @@ class BadwordsDelCallback : public NumberList
public:
BadwordsDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0), override(false)
{
if (!ci->AccessFor(source.u).HasPriv(CA_BADWORDS) && source.u->HasPriv("botserv/administration"))
if (!ci->AccessFor(source.u).HasPriv("BADWORDS") && source.u->HasPriv("botserv/administration"))
this->override = true;
}
@@ -90,20 +54,46 @@ class CommandBSBadwords : public Command
private:
void DoList(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "LIST";
ListFormatter list;
list.addColumn("Number").addColumn("Word").addColumn("Type");
if (!ci->GetBadWordCount())
{
source.Reply(_("%s bad words list is empty."), ci->name.c_str());
return;
}
else if (!word.empty() && word.find_first_not_of("1234567890,-") == Anope::string::npos)
{
BadwordsListCallback list(source, ci, word);
list.Process();
class BadwordsListCallback : public NumberList
{
ListFormatter &list;
ChannelInfo *ci;
public:
BadwordsListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetBadWordCount())
return;
BadWord *bw = ci->GetBadWord(Number - 1);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(Number);
entry["Word"] = bw->word;
entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : ""));
this->list.addEntry(entry);
}
}
nl_list(list, ci, word);
nl_list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
BadWord *bw = ci->GetBadWord(i);
@@ -111,28 +101,34 @@ class CommandBSBadwords : public Command
if (!word.empty() && !Anope::Match(bw->word, word))
continue;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Bad words list for %s:\n"
" Num Word Type"), ci->name.c_str());
}
BadwordsListCallback::DoList(source, i, bw);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Word"] = bw->word;
entry["Type"] = bw->type == BW_SINGLE ? "(SINGLE)" : (bw->type == BW_START ? "(START)" : (bw->type == BW_END ? "(END)" : ""));
list.addEntry(entry);
}
if (!SentHeader)
source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str());
}
return;
if (list.isEmpty())
source.Reply(_("No matching entries on %s badword list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Badword list for %s:"), ci->name.c_str());
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("End of badword list."));
}
}
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &word)
{
size_t pos = word.rfind(' ');
BadWordType type = BW_ANY;
BadWordType bwtype = BW_ANY;
Anope::string realword = word;
if (pos != Anope::string::npos)
@@ -141,11 +137,11 @@ class CommandBSBadwords : public Command
if (!opt.empty())
{
if (opt.equals_ci("SINGLE"))
type = BW_SINGLE;
bwtype = BW_SINGLE;
else if (opt.equals_ci("START"))
type = BW_START;
bwtype = BW_START;
else if (opt.equals_ci("END"))
type = BW_END;
bwtype = BW_END;
}
realword = word.substr(0, pos);
}
@@ -167,9 +163,9 @@ class CommandBSBadwords : public Command
}
}
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "ADD " << realword;
ci->AddBadWord(realword, type);
ci->AddBadWord(realword, bwtype);
source.Reply(_("\002%s\002 added to %s bad words list."), realword.c_str(), ci->name.c_str());
@@ -203,7 +199,7 @@ class CommandBSBadwords : public Command
return;
}
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "DEL " << badword->word;
source.Reply(_("\002%s\002 deleted from %s bad words list."), badword->word.c_str(), ci->name.c_str());
@@ -216,7 +212,7 @@ class CommandBSBadwords : public Command
void DoClear(CommandSource &source, ChannelInfo *ci)
{
bool override = !ci->AccessFor(source.u).HasPriv(CA_BADWORDS);
bool override = !ci->AccessFor(source.u).HasPriv("BADWORDS");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, this, ci) << "CLEAR";
ci->ClearBadWords();
@@ -254,7 +250,7 @@ class CommandBSBadwords : public Command
}
if (!ci->AccessFor(u).HasPriv(CA_BADWORDS) && (!need_args || !u->HasPriv("botserv/administration")))
if (!ci->AccessFor(u).HasPriv("BADWORDS") && (!need_args || !u->HasPriv("botserv/administration")))
{
source.Reply(ACCESS_DENIED);
return;
@@ -324,7 +320,6 @@ class BSBadwords : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsbadwords);
}
};
+4 -5
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -69,8 +69,8 @@ class CommandBSBot : public Command
return;
}
/* Check the host is valid re RFC 2812 */
if (!isValidHost(host, 3))
/* Check the host is valid */
if (!IsValidHost(host))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return;
@@ -186,7 +186,7 @@ class CommandBSBot : public Command
return;
}
if (!host.empty() && !isValidHost(host, 3))
if (!host.empty() && !IsValidHost(host))
{
source.Reply(_("Bot Hosts may only contain valid host characters."));
return;
@@ -407,7 +407,6 @@ class BSBot : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsbot);
}
};
+20 -24
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -26,50 +26,47 @@ class CommandBSBotList : public Command
{
User *u = source.u;
unsigned count = 0;
ListFormatter list;
list.addColumn("Nick").addColumn("Mask");
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
{
BotInfo *bi = it->second;
if (!bi->HasFlag(BI_PRIVATE))
if (u->HasCommand("botserv/botlist") || !bi->HasFlag(BI_PRIVATE))
{
if (!count)
source.Reply(_("Bot list:"));
++count;
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
ListFormatter::ListEntry entry;
entry["Nick"] = (bi->HasFlag(BI_PRIVATE) ? "* " : "") + bi->nick;
entry["Mask"] = bi->GetIdent() + "@" + bi->host;
list.addEntry(entry);
}
}
if (u->HasCommand("botserv/botlist") && count < BotListByNick.size())
{
source.Reply(_("Bots reserved to IRC operators:"));
for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
{
BotInfo *bi = it->second;
if (bi->HasFlag(BI_PRIVATE))
{
source.Reply(" %-15s (%s@%s)", bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str());
++count;
}
}
}
std::vector<Anope::string> replies;
list.Process(replies);
if (!count)
source.Reply(_("There are no bots available at this time.\n"
"Ask a Services Operator to create one!"));
else
source.Reply(_("%d bots available."), count);
{
source.Reply(_("Bot list:"));
return;
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("%d bots available."), count);
}
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Lists all available bots on this network."));
source.Reply(_("Lists all available bots on this network. Bots prefixed"
"by a * are reserved for IRC operators."));
return true;
}
};
@@ -84,7 +81,6 @@ class BSBotList : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsbotlist);
}
};
+3 -5
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -35,7 +35,7 @@ class CommandBSSay : public Command
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SAY))
if (!ci->AccessFor(u).HasPriv("SAY"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -98,7 +98,7 @@ class CommandBSAct : public Command
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SAY))
if (!ci->AccessFor(u).HasPriv("SAY"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -150,8 +150,6 @@ class BSControl : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbssay);
ModuleManager::RegisterService(&commandbsact);
}
};
+95 -89
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -17,7 +17,7 @@
class CommandBSInfo : public Command
{
private:
void send_bot_channels(CommandSource &source, BotInfo *bi)
void send_bot_channels(std::vector<Anope::string> &buffers, BotInfo *bi)
{
Anope::string buf;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
@@ -26,19 +26,28 @@ class CommandBSInfo : public Command
if (ci->bi == bi)
{
if (buf.length() + ci->name.length() > 300)
buf += " " + ci->name + " ";
if (buf.length() > 300)
{
source.Reply("%s", buf.c_str());
buffers.push_back(buf);
buf.clear();
}
buf += " " + ci->name + " ";
}
}
if (!buf.empty())
source.Reply("%s", buf.c_str());
return;
buffers.push_back(buf);
}
void CheckOptStr(Anope::string &buf, BotServFlag flag, const char *option, Flags<BotServFlag> &flags, NickCore *nc)
{
if (flags.HasFlag(flag))
{
if (!buf.empty())
buf += ", ";
buf += translate(nc, option);
}
}
public:
CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1)
{
@@ -50,168 +59,166 @@ class CommandBSInfo : public Command
{
const Anope::string &query = params[0];
bool need_comma = false;
char buf[BUFSIZE], *end;
User *u = source.u;
BotInfo *bi = findbot(query);
ChannelInfo *ci;
InfoFormatter info(u);
if (bi)
{
source.Reply(_("Information for bot \002%s\002:"), bi->nick.c_str());
source.Reply(_(" Mask : %s@%s"), bi->GetIdent().c_str(), bi->host.c_str());
source.Reply(_(" Real name : %s"), bi->realname.c_str());
source.Reply(_(" Created : %s"), do_strftime(bi->created).c_str());
source.Reply(_(" Options : %s"), bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None"));
source.Reply(_(" Used on : %d channel(s)"), bi->chancount);
info[_("Mask")] = bi->GetIdent() + "@" + bi->host;
info[_("Real name")] = bi->realname;
info[_("Created")] = do_strftime(bi->created);
info[_("Options")] = bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None");
info[_("Used on")] = stringify(bi->chancount) + " channel(s)";
std::vector<Anope::string> replies;
info.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
if (u->HasPriv("botserv/administration"))
this->send_bot_channels(source, bi);
{
std::vector<Anope::string> buf;
this->send_bot_channels(buf, bi);
for (unsigned i = 0; i < buf.size(); ++i)
source.Reply(buf[i]);
}
}
else if ((ci = cs_findchan(query)))
{
if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("botserv/administration"))
if (!ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasPriv("botserv/administration"))
{
source.Reply(ACCESS_DENIED);
return;
}
source.Reply(CHAN_INFO_HEADER, ci->name.c_str());
if (ci->bi)
source.Reply(_(" Bot nick : %s"), ci->bi->nick.c_str());
else
source.Reply(_(" Bot nick : not assigned yet."));
info[_("Bot nick")] = ci->bi ? ci->bi->nick : "not assigned yet";
Anope::string enabled = translate(u, _("Enabled"));
Anope::string disabled = translate(u, _("Disabled"));
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
if (ci->ttb[TTB_BADWORDS])
source.Reply(_(" Bad words kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BADWORDS]);
info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BADWORDS]);
else
source.Reply(_(" Bad words kicker : %s"), ENABLED);
info[_("Bad words kicker")] = enabled;
}
else
source.Reply(_(" Bad words kicker : %s"), DISABLED);
info[_("Bad words kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_BOLDS))
{
if (ci->ttb[TTB_BOLDS])
source.Reply(_(" Bolds kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_BOLDS]);
info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BOLDS]);
else
source.Reply(_(" Bolds kicker : %s"), ENABLED);
info[_("Bolds kicker")] = enabled;
}
else
source.Reply(_(" Bolds kicker : %s"), DISABLED);
info[_("Bolds kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_CAPS))
{
if (ci->ttb[TTB_CAPS])
source.Reply(_(" Caps kicker : %s (%d kick(s) to ban; minimum %d/%d%%)"), ENABLED, ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%"), enabled.c_str(), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent);
else
source.Reply(_(" Caps kicker : %s (minimum %d/%d%%)"), ENABLED, ci->capsmin, ci->capspercent);
info[_("Caps kicker")] = Anope::printf(_("%s (minimum %d/%d%%)"), enabled.c_str(), ci->capsmin, ci->capspercent);
}
else
source.Reply(_(" Caps kicker : %s"), DISABLED);
info[_("Caps kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_COLORS))
{
if (ci->ttb[TTB_COLORS])
source.Reply(_(" Colors kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_COLORS]);
info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_COLORS]);
else
source.Reply(_(" Colors kicker : %s"), ENABLED);
info[_("Colors kicker")] = enabled;
}
else
source.Reply(_(" Colors kicker : %s"), DISABLED);
info[_("Colors kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
if (ci->ttb[TTB_FLOOD])
source.Reply(_(" Flood kicker : %s (%d kick(s) to ban; %d lines in %ds)"), ENABLED, ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds"), enabled.c_str(), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs);
else
source.Reply(_(" Flood kicker : %s (%d lines in %ds)"), ENABLED, ci->floodlines, ci->floodsecs);
info[_("Flood kicker")] = Anope::printf(_("%s (%d lines in %ds)"), enabled.c_str(), ci->floodlines, ci->floodsecs);
}
else
source.Reply(_(" Flood kicker : %s"), DISABLED);
info[_("Flood kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (ci->ttb[TTB_REPEAT])
source.Reply(_(" Repeat kicker : %s (%d kick(s) to ban; %d times)"), ENABLED, ci->ttb[TTB_REPEAT], ci->repeattimes);
info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), ci->ttb[TTB_REPEAT], ci->repeattimes);
else
source.Reply(_(" Repeat kicker : %s (%d times)"), ENABLED, ci->repeattimes);
info[_("Repeat kicker")] = Anope::printf(_("%s (%d times)"), enabled.c_str(), ci->repeattimes);
}
else
source.Reply(_(" Repeat kicker : %s"), DISABLED);
info[_("Repeat kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_REVERSES))
{
if (ci->ttb[TTB_REVERSES])
source.Reply(_(" Reverses kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_REVERSES]);
info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_REVERSES]);
else
source.Reply(_(" Reverses kicker : %s"), ENABLED);
info[_("Reverses kicker")] = enabled;
}
else
source.Reply(_(" Reverses kicker : %s"), DISABLED);
info[_("Reverses kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES))
{
if (ci->ttb[TTB_UNDERLINES])
source.Reply(_(" Underlines kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_UNDERLINES]);
info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_UNDERLINES]);
else
source.Reply(_(" Underlines kicker : %s"), ENABLED);
info[_("Underlines kicker")] = enabled;
}
else
source.Reply(_(" Underlines kicker : %s"), DISABLED);
info[_("Underlines kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_ITALICS))
{
if (ci->ttb[TTB_ITALICS])
source.Reply(_(" Italics kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_ITALICS]);
info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_ITALICS]);
else
source.Reply(_(" Italics kicker : %s"), ENABLED);
info[_("Italics kicker")] = enabled;
}
else
source.Reply(_(" Italics kicker : %s"), DISABLED);
info[_("Italics kicker")] = disabled;
if (ci->botflags.HasFlag(BS_KICK_AMSGS))
{
if (ci->ttb[TTB_AMSGS])
source.Reply(_(" AMSG kicker : %s (%d kick(s) to ban)"), ENABLED, ci->ttb[TTB_AMSGS]);
info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_AMSGS]);
else
source.Reply(_(" AMSG kicker : %s"), ENABLED);
info[_("AMSG kicker")] = enabled;
}
else
source.Reply(_(" AMSG kicker : %s"), DISABLED);
info[_("AMSG kicker")] = disabled;
if (ci->botflags.HasFlag(BS_MSG_PRIVMSG))
source.Reply(_(" Fantasy reply : %s"), "PRIVMSG");
else if (ci->botflags.HasFlag(BS_MSG_NOTICE))
source.Reply(_(" Fantasy reply : %s"), "NOTICE");
else if (ci->botflags.HasFlag(BS_MSG_NOTICEOPS))
source.Reply(_(" Fantasy reply : %s"), "NOTICEOPS");
end = buf;
*end = 0;
if (ci->botflags.HasFlag(BS_DONTKICKOPS))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s", _("Ops protection"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_DONTKICKVOICES))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Voices protection"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_FANTASY))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Fantasy"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_GREET))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("Greet"));
need_comma = true;
}
if (ci->botflags.HasFlag(BS_NOBOT))
{
end += snprintf(end, sizeof(buf) - (end - buf), "%s%s", need_comma ? ", " : "", _("No bot"));
need_comma = true;
}
source.Reply(_(" Options : %s"), *buf ? buf : _("None"));
Anope::string flags;
CheckOptStr(flags, BS_DONTKICKOPS, _("Ops protection"), ci->botflags, u->Account());
CheckOptStr(flags, BS_DONTKICKVOICES, _("Voices protection"), ci->botflags, u->Account());
CheckOptStr(flags, BS_FANTASY, _("Fantasy"), ci->botflags, u->Account());
CheckOptStr(flags, BS_GREET, _("Greet"), ci->botflags, u->Account());
CheckOptStr(flags, BS_NOBOT, _("No bot"), ci->botflags, u->Account());
info[_("Options")] = flags.empty() ? _("None") : flags;
std::vector<Anope::string> replies;
info.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
else
source.Reply(_("\002%s\002 is not a valid bot or registered channel."), query.c_str());
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -237,7 +244,6 @@ class BSInfo : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsinfo);
}
};
+303 -285
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -41,13 +41,13 @@ class CommandBSKick : public Command
this->OnSyntaxError(source, "");
else if (!value.equals_ci("ON") && !value.equals_ci("OFF"))
this->OnSyntaxError(source, "");
else if (!ci->AccessFor(u).HasPriv(CA_SET) && !u->HasPriv("botserv/administration"))
else if (!ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("botserv/administration"))
source.Reply(ACCESS_DENIED);
else if (!ci->bi)
source.Reply(BOT_NOT_ASSIGNED);
else
{
bool override = !ci->AccessFor(u).HasPriv(CA_SET);
bool override = !ci->AccessFor(u).HasPriv("SET");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("BADWORDS"))
@@ -58,7 +58,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_BADWORDS] = convertTo<int16>(ttb);
ci->ttb[TTB_BADWORDS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_BADWORDS] < 0)
throw ConvertException();
}
@@ -96,7 +96,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_BOLDS] = convertTo<int16>(ttb);
ci->ttb[TTB_BOLDS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_BOLDS] < 0)
throw ConvertException();
}
@@ -132,7 +132,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_CAPS] = convertTo<int16>(ttb);
ci->ttb[TTB_CAPS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_CAPS] < 0)
throw ConvertException();
}
@@ -149,7 +149,7 @@ class CommandBSKick : public Command
ci->capsmin = 10;
try
{
ci->capsmin = convertTo<int16>(min);
ci->capsmin = convertTo<int16_t>(min);
}
catch (const ConvertException &) { }
if (ci->capsmin < 1)
@@ -158,7 +158,7 @@ class CommandBSKick : public Command
ci->capspercent = 25;
try
{
ci->capspercent = convertTo<int16>(percent);
ci->capspercent = convertTo<int16_t>(percent);
}
catch (const ConvertException &) { }
if (ci->capspercent < 1 || ci->capspercent > 100)
@@ -187,7 +187,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_COLORS] = convertTo<int16>(ttb);
ci->ttb[TTB_COLORS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_COLORS] < 1)
throw ConvertException();
}
@@ -224,7 +224,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_FLOOD] = convertTo<int16>(ttb);
ci->ttb[TTB_FLOOD] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_FLOOD] < 1)
throw ConvertException();
}
@@ -241,7 +241,7 @@ class CommandBSKick : public Command
ci->floodlines = 6;
try
{
ci->floodlines = convertTo<int16>(lines);
ci->floodlines = convertTo<int16_t>(lines);
}
catch (const ConvertException &) { }
if (ci->floodlines < 2)
@@ -250,7 +250,7 @@ class CommandBSKick : public Command
ci->floodsecs = 10;
try
{
ci->floodsecs = convertTo<int16>(secs);
ci->floodsecs = convertTo<int16_t>(secs);
}
catch (const ConvertException &) { }
if (ci->floodsecs < 1)
@@ -280,7 +280,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_REPEAT] = convertTo<int16>(ttb);
ci->ttb[TTB_REPEAT] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_REPEAT] < 0)
throw ConvertException();
}
@@ -297,7 +297,7 @@ class CommandBSKick : public Command
ci->repeattimes = 3;
try
{
ci->repeattimes = convertTo<int16>(times);
ci->repeattimes = convertTo<int16_t>(times);
}
catch (const ConvertException &) { }
if (ci->repeattimes < 2)
@@ -305,12 +305,12 @@ class CommandBSKick : public Command
ci->botflags.SetFlag(BS_KICK_REPEAT);
if (ci->ttb[TTB_REPEAT])
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
"the same thing), and will place a ban after %d \n"
source.Reply(_("Bot will now kick \002repeats\002 (users that say the\n"
"same thing %d times), and will place a ban after %d \n"
"kicks for the same user."), ci->repeattimes, ci->ttb[TTB_REPEAT]);
else
source.Reply(_("Bot will now kick \002repeats\002 (users that say %d times\n"
"the same thing)."), ci->repeattimes);
source.Reply(_("Bot will now kick \002repeats\002 (users that say the\n"
"same thing %d times)."), ci->repeattimes);
}
else
{
@@ -326,7 +326,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_REVERSES] = convertTo<int16>(ttb);
ci->ttb[TTB_REVERSES] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_REVERSES] < 0)
throw ConvertException();
}
@@ -359,7 +359,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_UNDERLINES] = convertTo<int16>(ttb);
ci->ttb[TTB_UNDERLINES] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_REVERSES] < 0)
throw ConvertException();
}
@@ -393,7 +393,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_ITALICS] = convertTo<int16>(ttb);
ci->ttb[TTB_ITALICS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_ITALICS] < 0)
throw ConvertException();
}
@@ -427,7 +427,7 @@ class CommandBSKick : public Command
{
try
{
ci->ttb[TTB_AMSGS] = convertTo<int16>(ttb);
ci->ttb[TTB_AMSGS] = convertTo<int16_t>(ttb);
if (ci->ttb[TTB_AMSGS] < 0)
throw ConvertException();
}
@@ -454,7 +454,7 @@ class CommandBSKick : public Command
}
}
else
source.Reply(UNKNOWN_OPTION, Config->UseStrictPrivMsgString.c_str(), option.c_str(), this->name.c_str());
this->OnSyntaxError(source, "");
}
return;
}
@@ -577,26 +577,62 @@ class CommandBSKick : public Command
}
};
struct BanData
struct BanData : public ExtensibleItem
{
Anope::string mask;
time_t last_use;
int16 ttb[TTB_SIZE];
BanData()
struct Data
{
this->Clear();
Anope::string mask;
time_t last_use;
int16_t ttb[TTB_SIZE];
Data()
{
this->Clear();
}
void Clear()
{
last_use = 0;
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
}
};
private:
typedef std::map<Anope::string, Data, ci::less> data_type;
data_type data_map;
public:
Data &get(const Anope::string &key)
{
return this->data_map[key];
}
void Clear()
bool empty() const
{
last_use = 0;
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
return this->data_map.empty();
}
void purge()
{
for (data_type::iterator it = data_map.begin(), it_end = data_map.end(); it != it_end;)
{
const Anope::string &user = it->first;
Data &bd = it->second;
++it;
if (Anope::CurTime - bd.last_use > Config->BSKeepData)
data_map.erase(user);
}
}
void OnDelete()
{
delete this;
}
};
struct UserData
struct UserData : public ExtensibleItem
{
UserData()
{
@@ -614,13 +650,19 @@ struct UserData
time_t last_use;
/* for flood kicker */
int16 lines;
int16_t lines;
time_t last_start;
/* for repeat kicker */
Anope::string lastline;
Anope::string lasttarget;
int16 times;
int16_t times;
Anope::string lastline;
void OnDelete()
{
delete this;
}
};
@@ -636,24 +678,12 @@ class BanDataPurger : public CallBack
for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
{
Channel *c = it->second;
std::map<Anope::string, BanData> bandata;
if (c->GetExtRegular("bs_main_bandata", bandata))
BanData *bd = c->GetExt<BanData *>("bs_main_bandata");
if (bd != NULL)
{
for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end;)
{
const Anope::string &user = it2->first;
BanData *bd = &it2->second;
++it2;
if (Anope::CurTime - bd->last_use > Config->BSKeepData)
{
bandata.erase(user);
continue;
}
}
if (bandata.empty())
bd->purge();
if (bd->empty())
c->Shrink("bs_main_bandata");
}
}
@@ -665,30 +695,32 @@ class BSKick : public Module
CommandBSKick commandbskick;
BanDataPurger purger;
BanData *GetBanData(User *u, Channel *c)
BanData::Data &GetBanData(User *u, Channel *c)
{
std::map<Anope::string, BanData> bandatamap;
if (!c->GetExtRegular("bs_main_bandata", bandatamap));
c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
c->GetExtRegular("bs_main_bandata", bandatamap);
BanData *bd = c->GetExt<BanData *>("bs_main_bandata");
if (bd == NULL)
{
bd = new BanData();
c->Extend("bs_main_bandata", bd);
}
BanData *bd = &bandatamap[u->GetMask()];
if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
bd->Clear();
bd->last_use = Anope::CurTime;
return bd;
return bd->get(u->GetMask());
}
UserData *GetUserData(User *u, Channel *c)
{
UserData *ud = NULL;
UserContainer *uc = c->FindUser(u);
if (uc != NULL && !uc->GetExtPointer("bs_main_userdata", ud))
if (uc == NULL)
return NULL;
UserData *ud = uc->GetExt<UserData *>("bs_main_userdata");
if (ud == NULL)
{
ud = new UserData();
uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
uc->Extend("bs_main_userdata", ud);
}
return ud;
return ud;
}
void check_ban(ChannelInfo *ci, User *u, int ttbtype)
@@ -697,17 +729,17 @@ class BSKick : public Module
if (u->server->IsULined())
return;
BanData *bd = this->GetBanData(u, ci->c);
BanData::Data &bd = this->GetBanData(u, ci->c);
++bd->ttb[ttbtype];
if (ci->ttb[ttbtype] && bd->ttb[ttbtype] >= ci->ttb[ttbtype])
++bd.ttb[ttbtype];
if (ci->ttb[ttbtype] && bd.ttb[ttbtype] >= ci->ttb[ttbtype])
{
/* Should not use == here because bd->ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
/* Should not use == here because bd.ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
* if the TTB was changed after it was not set (0) before and the user had already been
* kicked a few times. Bug #1056 - Adam */
Anope::string mask;
bd->ttb[ttbtype] = 0;
bd.ttb[ttbtype] = 0;
get_idealban(ci, u, mask);
@@ -722,7 +754,7 @@ class BSKick : public Module
va_list args;
char buf[1024];
if (!ci || !ci->bi || !ci->c || !u || u->server->IsULined())
if (!ci || !ci->bi || !ci->c || !u || u->server->IsULined() || !ci->c->FindUser(u))
return;
Anope::string fmt = translate(u, message);
@@ -739,8 +771,6 @@ class BSKick : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbskick);
ModuleManager::Attach(I_OnPrivmsg, this);
}
@@ -748,8 +778,10 @@ class BSKick : public Module
{
for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit)
{
cit->second->Shrink("bs_main_userdata");
cit->second->Shrink("bs_main_bandata");
Channel *c = cit->second;
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
(*it)->Shrink("bs_main_userdata");
c->Shrink("bs_main_bandata");
}
}
@@ -768,242 +800,228 @@ class BSKick : public Module
return;
bool Allow = true;
if (ci->AccessFor(u).HasPriv(CA_NOKICK))
if (ci->AccessFor(u).HasPriv("NOKICK"))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (c->HasUserStatus(u, CMODE_HALFOP) || c->HasUserStatus(u, CMODE_OP) || c->HasUserStatus(u, CMODE_PROTECT) || c->HasUserStatus(u, CMODE_OWNER)))
Allow = false;
else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && c->HasUserStatus(u, CMODE_VOICE))
Allow = false;
if (Allow)
if (!Allow)
return;
Anope::string realbuf = msg;
/* If it's a /me, cut the CTCP part because the ACTION will cause
* problems with the caps or badwords kicker
*/
if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
{
Anope::string realbuf = msg;
realbuf.erase(0, 8);
realbuf.erase(realbuf.length() - 1);
}
/* If it's a /me, cut the CTCP part because the ACTION will cause
* problems with the caps or badwords kicker
if (realbuf.empty())
return;
/* Bolds kicker */
if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find(2) != Anope::string::npos)
{
check_ban(ci, u, TTB_BOLDS);
bot_kick(ci, u, _("Don't use bolds on this channel!"));
return;
}
/* Color kicker */
if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find(3) != Anope::string::npos)
{
check_ban(ci, u, TTB_COLORS);
bot_kick(ci, u, _("Don't use colors on this channel!"));
return;
}
/* Reverses kicker */
if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find(22) != Anope::string::npos)
{
check_ban(ci, u, TTB_REVERSES);
bot_kick(ci, u, _("Don't use reverses on this channel!"));
return;
}
/* Italics kicker */
if (ci->botflags.HasFlag(BS_KICK_ITALICS) && realbuf.find(29) != Anope::string::npos)
{
check_ban(ci, u, TTB_ITALICS);
bot_kick(ci, u, _("Don't use italics on this channel!"));
return;
}
/* Underlines kicker */
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find(31) != Anope::string::npos)
{
check_ban(ci, u, TTB_UNDERLINES);
bot_kick(ci, u, _("Don't use underlines on this channel!"));
return;
}
/* Caps kicker */
if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= static_cast<unsigned>(ci->capsmin))
{
int i = 0, l = 0;
for (unsigned j = 0, end = realbuf.length(); j < end; ++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 (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
{
realbuf.erase(0, 8);
realbuf.erase(realbuf.length() - 1);
}
if (realbuf.empty())
return;
/* Bolds kicker */
if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find(2) != Anope::string::npos)
if ((i || l) && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent)
{
check_ban(ci, u, TTB_BOLDS);
bot_kick(ci, u, _("Don't use bolds on this channel!"));
check_ban(ci, u, TTB_CAPS);
bot_kick(ci, u, _("Turn caps lock OFF!"));
return;
}
}
/* Color kicker */
if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find(3) != Anope::string::npos)
{
check_ban(ci, u, TTB_COLORS);
bot_kick(ci, u, _("Don't use colors on this channel!"));
return;
}
/* Bad words kicker */
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
bool mustkick = false;
/* Reverses kicker */
if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find(22) != Anope::string::npos)
{
check_ban(ci, u, TTB_REVERSES);
bot_kick(ci, u, _("Don't use reverses on this channel!"));
return;
}
/* Normalize the buffer */
Anope::string nbuf = normalizeBuffer(realbuf);
/* Italics kicker */
if (ci->botflags.HasFlag(BS_KICK_ITALICS) && realbuf.find(29) != Anope::string::npos)
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
check_ban(ci, u, TTB_ITALICS);
bot_kick(ci, u, _("Don't use italics on this channel!"));
return;
}
BadWord *bw = ci->GetBadWord(i);
/* Underlines kicker */
if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find(31) != Anope::string::npos)
{
check_ban(ci, u, TTB_UNDERLINES);
bot_kick(ci, u, _("Don't use underlines on this channel!"));
return;
}
/* Caps kicker */
if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->capsmin)
{
int i = 0, l = 0;
for (unsigned j = 0, end = realbuf.length(); j < end; ++j)
if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
mustkick = true;
else if (bw->type == BW_SINGLE)
{
if (isupper(realbuf[j]))
++i;
else if (islower(realbuf[j]))
++l;
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))
mustkick = true;
else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))))
mustkick = true;
else
{
if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
}
else if (bw->type == BW_START)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word;
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
else if (bw->type == BW_END)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
/* 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 (mustkick)
{
check_ban(ci, u, TTB_CAPS);
bot_kick(ci, u, _("Turn caps lock OFF!"));
check_ban(ci, u, TTB_BADWORDS);
if (Config->BSGentleBWReason)
bot_kick(ci, u, _("Watch your language!"));
else
bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
return;
}
} /* for */
} /* if badwords */
UserData *ud = GetUserData(u, c);
if (ud)
{
/* Flood kicker */
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
if (Anope::CurTime - ud->last_start > ci->floodsecs)
{
ud->last_start = Anope::CurTime;
ud->lines = 0;
}
++ud->lines;
if (ud->lines >= ci->floodlines)
{
check_ban(ci, u, TTB_FLOOD);
bot_kick(ci, u, _("Stop flooding!"));
return;
}
}
/* Bad words kicker */
if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
/* Repeat kicker */
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
bool mustkick = false;
if (!ud->lastline.equals_ci(realbuf))
ud->times = 0;
else
++ud->times;
/* Normalize the buffer */
Anope::string nbuf = normalizeBuffer(realbuf);
for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
if (ud->times >= ci->repeattimes)
{
BadWord *bw = ci->GetBadWord(i);
if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
mustkick = true;
else if (bw->type == BW_SINGLE)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))
mustkick = true;
else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))))
mustkick = true;
else
{
if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
}
else if (bw->type == BW_START)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = " " + bw->word;
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
else if (bw->type == BW_END)
{
size_t len = bw->word.length();
if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
mustkick = true;
else
{
Anope::string wordbuf = bw->word + " ";
if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
mustkick = true;
}
}
if (mustkick)
{
check_ban(ci, u, TTB_BADWORDS);
if (Config->BSGentleBWReason)
bot_kick(ci, u, _("Watch your language!"));
else
bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
return;
}
check_ban(ci, u, TTB_REPEAT);
bot_kick(ci, u, _("Stop repeating yourself!"));
return;
}
UserData *ud = NULL;
/* Flood kicker */
if (ci->botflags.HasFlag(BS_KICK_FLOOD))
{
ud = GetUserData(u, c);
if (ud)
{
if (Anope::CurTime - ud->last_start > ci->floodsecs)
{
ud->last_start = Anope::CurTime;
ud->lines = 0;
}
++ud->lines;
if (ud->lines >= ci->floodlines)
{
check_ban(ci, u, TTB_FLOOD);
bot_kick(ci, u, _("Stop flooding!"));
return;
}
}
}
/* Repeat kicker */
if (ci->botflags.HasFlag(BS_KICK_REPEAT))
{
if (!ud)
ud = GetUserData(u, c);
if (ud)
{
if (!ud->lastline.empty() && !ud->lastline.equals_ci(realbuf))
{
ud->lastline = realbuf;
ud->times = 0;
}
else
{
if (ud->lastline.empty())
ud->lastline = realbuf;
++ud->times;
}
if (ud->times >= ci->repeattimes)
{
check_ban(ci, u, TTB_REPEAT);
bot_kick(ci, u, _("Stop repeating yourself!"));
return;
}
}
}
if (ud && ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *chan = (*it)->chan;
++it;
if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv(CA_NOKICK))
{
check_ban(chan->ci, u, TTB_AMSGS);
bot_kick(chan->ci, u, _("Don't use AMSGs!"));
}
}
}
if (ud)
ud->lasttarget = ci->name;
}
if (ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
{
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
{
Channel *chan = (*it)->chan;
++it;
if (chan->ci != NULL && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
{
check_ban(chan->ci, u, TTB_AMSGS);
bot_kick(chan->ci, u, _("Don't use AMSGs!"));
}
}
}
ud->lasttarget = ci->name;
ud->lastline = realbuf;
}
}
};
+3 -49
View File
@@ -1,6 +1,6 @@
/* BotServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -59,11 +59,11 @@ class CommandBSSet : public Command
}
else if (!(ci = cs_findchan(chan)))
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv(CA_SET))
else if (!u->HasPriv("botserv/administration") && !ci->AccessFor(u).HasPriv("SET"))
source.Reply(ACCESS_DENIED);
else
{
bool override = !ci->AccessFor(u).HasPriv(CA_SET);
bool override = !ci->AccessFor(u).HasPriv("SET");
Log(override ? LOG_ADMIN : LOG_COMMAND, u, this, ci) << option << " " << value;
if (option.equals_ci("DONTKICKOPS"))
@@ -143,39 +143,6 @@ class CommandBSSet : public Command
else
this->OnSyntaxError(source, "NOBOT");
}
else if (option.equals_ci("MSG"))
{
if (value.equals_ci("OFF"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will no longer be sent to %s."), ci->name.c_str());
}
else if (value.equals_ci("PRIVMSG"))
{
ci->botflags.SetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via PRIVMSG to %s."), ci->name.c_str());
}
else if (value.equals_ci("NOTICE"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.SetFlag(BS_MSG_NOTICE);
ci->botflags.UnsetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via NOTICE to %s."), ci->name.c_str());
}
else if (value.equals_ci("NOTICEOPS"))
{
ci->botflags.UnsetFlag(BS_MSG_PRIVMSG);
ci->botflags.UnsetFlag(BS_MSG_NOTICE);
ci->botflags.SetFlag(BS_MSG_NOTICEOPS);
source.Reply(_("Fantasy replies will be sent via NOTICE to channel ops on %s."), ci->name.c_str());
}
else
this->OnSyntaxError(source, "MSG");
}
else
this->OnSyntaxError(source, "");
}
@@ -195,7 +162,6 @@ class CommandBSSet : public Command
" DONTKICKVOICES To protect voices against bot kicks\n"
" GREET Enable greet messages\n"
" FANTASY Enable fantaisist commands\n"
" MSG Configure how fantasy commands should be replied to\n"
" \n"
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
"on a specific option.\n"
@@ -254,15 +220,6 @@ class CommandBSSet : public Command
source.Reply(_("Syntax: \002SET \037bot-nick\037 PRIVATE {\037ON|OFF\037}\002\n"
"This option prevents a bot from being assigned to a\n"
"channel by users that aren't IRC operators."));
else if (subcommand.equals_ci("MSG"))
source.Reply(_("Syntax: \002SET \037channel\037 MSG {\037OFF|PRIVMSG|NOTICE|NOTICEOPS\037}\002\n"
" \n"
"Configures how fantasy commands should be returned to the channel. Off disables\n"
"fantasy from replying to the channel. Privmsg, notice, and noticeops message the\n"
"channel, notice the channel, and notice the channel ops respectively.\n"
" \n"
"Note that replies over one line will not use this setting to prevent spam, and will\n"
"go directly to the user who executed it."));
else
return false;
@@ -283,8 +240,6 @@ class CommandBSSet : public Command
this->SendSyntax(source, "\037channel\037 FANTASY {\037ON|OFF\037}");
else if (subcommand.equals_ci("GREET"))
this->SendSyntax(source, "\037channel\037 GREET {\037ON|OFF\037}");
else if (subcommand.equals_ci("MSG"))
this->SendSyntax(source, "\037channel\037 MSG {\037PRIVMSG|NOTICE|NOTICEOPS|OFF\037}");
else if (subcommand.equals_ci("NOBOT"))
this->SendSyntax(source, "\037channel\037 NOBOT {\037ON|OFF\037}");
else
@@ -302,7 +257,6 @@ class BSSet : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandbsset);
}
};
+270 -356
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -13,63 +13,13 @@
#include "module.h"
enum
{
ACCESS_INVALID = -10000,
ACCESS_FOUNDER = 10001
};
static struct AccessLevels
{
ChannelAccess priv;
int default_level;
Anope::string config_name;
Anope::string name;
Anope::string desc;
} defaultLevels[] = {
{ CA_ACCESS_CHANGE, 10, "level_change", "ACC-CHANGE", _("Allowed to modify the access list") },
{ CA_ACCESS_LIST, 1, "level_list", "ACC-LIST", _("Allowed to view the access list") },
{ CA_AKICK, 10, "level_akick", "AKICK", _("Allowed to use AKICK command") },
{ CA_ASSIGN, ACCESS_FOUNDER, "level_assign", "ASSIGN", _("Allowed to assign/unassign a bot") },
{ CA_AUTOHALFOP, 4, "level_autohalfop", "AUTOHALFOP", _("Automatic mode +h") },
{ CA_AUTOOP, 5, "level_autoop", "AUTOOP", _("Automatic channel operator status") },
{ CA_AUTOOWNER, 10000, "level_autoowner", "AUTOOWNER", _("Automatic mode +q") },
{ CA_AUTOPROTECT, 10, "level_autoprotect", "AUTOPROTECT", _("Automatic mode +a") },
{ CA_AUTOVOICE, 3, "level_autovoice", "AUTOVOICE", _("Automatic mode +v") },
{ CA_BADWORDS, 10, "level_badwords", "BADWORDS", _("Allowed to modify channel badwords list") },
{ CA_BAN, 4, "level_ban", "BAN", _("Allowed to use ban users") },
{ CA_FANTASIA, 3, "level_fantasia", "FANTASIA", _("Allowed to use fantaisist commands") },
{ CA_FOUNDER, ACCESS_FOUNDER, "level_founder", "FOUNDER", _("Allowed to issue commands restricted to channel founders") },
{ CA_GETKEY, 5, "level_getkey", "GETKEY", _("Allowed to use GETKEY command") },
{ CA_GREET, 5, "level_greet", "GREET", _("Greet message displayed") },
{ CA_HALFOP, 5, "level_halfop", "HALFOP", _("Allowed to (de)halfop users") },
{ CA_HALFOPME, 4, "level_halfopme", "HALFOPME", _("Allowed to (de)halfop him/herself") },
{ CA_INFO, 10000, "level_info", "INFO", _("Allowed to use INFO command with ALL option") },
{ CA_INVITE, 5, "level_invite", "INVITE", _("Allowed to use the INVITE command") },
{ CA_KICK, 4, "level_kick", "KICK", _("Allowed to use the KICK command") },
{ CA_MEMO, 10, "level_memo", "MEMO", _("Allowed to read channel memos") },
{ CA_MODE, 5, "level_mode", "MODE", _("Allowed to change channel modes") },
{ CA_NOKICK, 1, "level_nokick", "NOKICK", _("Never kicked by the bot's kickers") },
{ CA_OPDEOP, 5, "level_opdeop", "OPDEOP", _("Allowed to (de)op users") },
{ CA_OPDEOPME, 5, "level_opdeopme", "OPDEOPME", _("Allowed to (de)op him/herself") },
{ CA_OWNER, ACCESS_FOUNDER, "level_owner", "OWNER", _("Allowed to use (de)owner users") },
{ CA_OWNERME, 10000, "level_ownerme", "OWNERME", _("Allowed to (de)owner him/herself") },
{ CA_PROTECT, 10000, "level_protect", "PROTECT", _("Allowed to (de)protect users") },
{ CA_PROTECTME, 10, "level_protectme", "PROTECTME", _("Allowed to (de)protect him/herself"), },
{ CA_SAY, 5, "level_say", "SAY", _("Allowed to use SAY and ACT commands") },
{ CA_SIGNKICK, ACCESS_FOUNDER, "level_signkick", "SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used") },
{ CA_SET, 10000, "level_set", "SET", _("Allowed to set channel settings") },
{ CA_TOPIC, 5, "level_topic", "TOPIC", _("Allowed to change channel topics") },
{ CA_UNBAN, 4, "level_unban", "UNBAN", _("Allowed to unban users") },
{ CA_VOICE, 4, "level_voice", "VOICE", _("Allowed to (de)voice users") },
{ CA_VOICEME, 3, "level_voiceme", "VOICEME", _("Allowed to (de)voice him/herself") },
{ CA_SIZE, -1, "", "", "" }
};
static std::map<Anope::string, int16_t, ci::less> defaultLevels;
static void reset_levels(ChannelInfo *ci)
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
ci->levels[defaultLevels[i].priv] = defaultLevels[i].default_level;
ci->ClearLevels();
for (std::map<Anope::string, int16_t, ci::less>::iterator it = defaultLevels.begin(), it_end = defaultLevels.end(); it != it_end; ++it)
ci->SetLevel(it->first, it->second);
}
class AccessChanAccess : public ChanAccess
@@ -81,21 +31,9 @@ class AccessChanAccess : public ChanAccess
{
}
bool Matches(User *u, NickCore *nc)
bool HasPriv(const Anope::string &name) const
{
if (u && this->mask.find_first_of("!@?*") != Anope::string::npos && (Anope::Match(u->nick, this->mask) || Anope::Match(u->GetMask(), this->mask)))
return true;
else if (nc && Anope::Match(nc->display, this->mask))
return true;
return false;
}
bool HasPriv(ChannelAccess priv)
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
if (defaultLevels[i].priv == priv)
return this->ci->levels[priv] != ACCESS_INVALID && DetermineLevel(this) >= this->ci->levels[priv];
return false;
return this->ci->GetLevel(name) != ACCESS_INVALID && this->level >= this->ci->GetLevel(name);
}
Anope::string Serialize()
@@ -118,11 +56,18 @@ class AccessChanAccess : public ChanAccess
else
{
int highest = 1;
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
if (access->ci->levels[defaultLevels[i].priv] > highest && access->HasPriv(defaultLevels[i].priv))
highest = access->ci->levels[defaultLevels[i].priv];
const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
for (unsigned i = 0; i < privs.size(); ++i)
{
const Privilege &p = privs[i];
if (access->ci->GetLevel(p.name) > highest && access->HasPriv(p.name))
highest = access->ci->GetLevel(p.name);
}
if (highest >= ACCESS_FOUNDER)
highest = ACCESS_FOUNDER - 1;
return highest;
}
}
@@ -141,148 +86,6 @@ class AccessAccessProvider : public AccessProvider
}
};
class AccessListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AccessListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AccessListCallback()
{
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
source.Reply(_(" %3d %4d %s"), Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str());
}
};
class AccessViewCallback : public AccessListCallback
{
public:
AccessViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AccessListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAccess(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
Anope::string timebuf;
if (ci->c)
for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
if (access->Matches((*cit)->user, (*cit)->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
if (access->last_seen == 0)
timebuf = "Never";
else
timebuf = do_strftime(access->last_seen, NULL, true);
}
source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, AccessChanAccess::DetermineLevel(access), access->mask.c_str(), access->creator.c_str(), do_strftime(access->created, NULL, true).c_str(), timebuf.c_str());
}
};
class AccessDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool Denied;
bool override;
public:
AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false)
{
if (!ci->AccessFor(source.u).HasPriv(CA_ACCESS_CHANGE) && source.u->HasPriv("chanserv/access/modify"))
this->override = true;
}
~AccessDelCallback()
{
if (Denied && !Deleted)
source.Reply(ACCESS_DENIED);
else if (!Deleted)
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "for user" << (Deleted == 1 ? " " : "s ") << Nicks;
if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s access list."), Deleted, ci->name.c_str());
}
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
User *u = source.u;
ChanAccess *access = ci->GetAccess(Number - 1);
AccessGroup u_access = ci->AccessFor(u);
ChanAccess *u_highest = u_access.Highest();
if (u_highest ? AccessChanAccess::DetermineLevel(u_highest) : 0 <= AccessChanAccess::DetermineLevel(access) && !u->HasPriv("chanserv/access/modify"))
{
Denied = true;
return;
}
++Deleted;
if (!Nicks.empty())
Nicks += ", " + access->mask;
else
Nicks = access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(Number - 1);
}
};
class CommandCSAccess : public Command
{
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -291,7 +94,7 @@ class CommandCSAccess : public Command
Anope::string mask = params[2];
int level = ACCESS_INVALID;
try
{
level = convertTo<int>(params[3]);
@@ -318,7 +121,7 @@ class CommandCSAccess : public Command
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE) || (level >= u_level && !u_access.Founder);
bool override = !ci->AccessFor(u).HasPriv("ACCESS_CHANGE") || (level >= u_level && !u_access.Founder);
if (mask.find_first_of("!*@") == Anope::string::npos && findnick(mask) == NULL)
mask += "!*@*";
@@ -345,7 +148,7 @@ class CommandCSAccess : public Command
return;
}
service_reference<AccessProvider> provider("access/access");
service_reference<AccessProvider> provider("AccessProvider", "access/access");
if (!provider)
return;
AccessChanAccess *access = debug_cast<AccessChanAccess *>(provider->Create());
@@ -359,7 +162,7 @@ class CommandCSAccess : public Command
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to add " << mask << " with level " << level;
source.Reply(_("\002%s\002 added to %s access list at level \002%d\002."), access->mask.c_str(), ci->name.c_str(), level);
return;
@@ -375,8 +178,70 @@ class CommandCSAccess : public Command
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessDelCallback list(source, ci, this, mask);
list.Process();
class AccessDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
Anope::string Nicks;
bool Denied;
bool override;
public:
AccessDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), Deleted(0), Denied(false), override(false)
{
if (!ci->AccessFor(source.u).HasPriv("ACCESS_CHANGE") && source.u->HasPriv("chanserv/access/modify"))
this->override = true;
}
~AccessDelCallback()
{
if (Denied && !Deleted)
source.Reply(ACCESS_DENIED);
else if (!Deleted)
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "to delete " << Nicks;
if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s access list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s access list."), Deleted, ci->name.c_str());
}
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAccessCount())
return;
User *user = source.u;
ChanAccess *access = ci->GetAccess(Number - 1);
AccessGroup u_access = ci->AccessFor(user);
ChanAccess *u_highest = u_access.Highest();
if ((u_highest ? AccessChanAccess::DetermineLevel(u_highest) : 0) <= AccessChanAccess::DetermineLevel(access) && !u_access.Founder && !this->override && !access->mask.equals_ci(user->Account()->display))
{
Denied = true;
return;
}
++Deleted;
if (!Nicks.empty())
Nicks += ", " + access->mask;
else
Nicks = access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, user, access));
ci->EraseAccess(Number - 1);
}
}
delcallback(source, ci, this, mask);
delcallback.Process();
}
else
{
@@ -395,8 +260,8 @@ class CommandCSAccess : public Command
else
{
source.Reply(_("\002%s\002 deleted from %s access list."), access->mask.c_str(), ci->name.c_str());
bool override = !u_access.Founder && !u_access.HasPriv(CA_ACCESS_CHANGE) && !access->mask.equals_ci(u->Account()->display);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask;
bool override = !u_access.Founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->mask.equals_ci(u->Account()->display);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to delete " << access->mask;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access));
ci->EraseAccess(access);
@@ -411,7 +276,7 @@ class CommandCSAccess : public Command
return;
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
{
const Anope::string &nick = params.size() > 2 ? params[2] : "";
@@ -419,13 +284,50 @@ class CommandCSAccess : public Command
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessListCallback list(source, ci, nick);
list.Process();
class AccessListCallback : public NumberList
{
ListFormatter &list;
ChannelInfo *ci;
public:
AccessListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
{
}
void HandleNumber(unsigned number)
{
if (!number || number > ci->GetAccessCount())
return;
ChanAccess *access = ci->GetAccess(number - 1);
Anope::string timebuf;
if (ci->c)
for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
if (access->Matches((*cit)->user, (*cit)->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
if (access->last_seen == 0)
timebuf = "Never";
else
timebuf = do_strftime(access->last_seen, NULL, true);
}
ListFormatter::ListEntry entry;
entry["Number"] = stringify(number);
entry["Level"] = stringify(AccessChanAccess::DetermineLevel(access));
entry["Mask"] = access->mask;
entry["By"] = access->creator;
entry["Last seen"] = timebuf;
this->list.addEntry(entry);
}
}
nl_list(list, ci, nick);
nl_list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
ChanAccess *access = ci->GetAccess(i);
@@ -433,62 +335,71 @@ class CommandCSAccess : public Command
if (!nick.empty() && !Anope::Match(access->mask, nick))
continue;
if (!SentHeader)
Anope::string timebuf;
if (ci->c)
for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
if (access->Matches((*cit)->user, (*cit)->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
if (access->last_seen == 0)
timebuf = "Never";
else
timebuf = do_strftime(access->last_seen, NULL, true);
}
AccessListCallback::DoList(source, ci, i, access);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Level"] = stringify(AccessChanAccess::DetermineLevel(access));
entry["Mask"] = access->mask;
entry["By"] = access->creator;
entry["Last seen"] = timebuf;
list.addEntry(entry);
}
}
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
if (list.isEmpty())
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Access list for %s:"), ci->name.c_str());
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("End of access list"));
}
return;
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
if (!ci->GetAccessCount())
{
source.Reply(_("%s access list is empty."), ci->name.c_str());
return;
}
ListFormatter list;
list.addColumn("Number").addColumn("Level").addColumn("Mask");
this->ProcessList(source, ci, params, list);
}
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
const Anope::string &nick = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
{
source.Reply(_("%s access list is empty."), ci->name.c_str());
else if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AccessViewCallback list(source, ci, nick);
list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
ChanAccess *access = ci->GetAccess(i);
if (!nick.empty() && !Anope::Match(access->mask, nick))
continue;
if (!SentHeader)
{
SentHeader = true;
source.Reply(CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
}
AccessViewCallback::DoList(source, ci, i, access);
}
if (SentHeader)
source.Reply(_("End of access list."));
else
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
return;
}
return;
ListFormatter list;
list.addColumn("Number").addColumn("Level").addColumn("Mask").addColumn("By").addColumn("Last seen");
this->ProcessList(source, ci, params, list);
}
void DoClear(CommandSource &source, ChannelInfo *ci)
@@ -499,14 +410,14 @@ class CommandCSAccess : public Command
source.Reply(ACCESS_DENIED);
else
{
ci->ClearAccess();
FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
ci->ClearAccess();
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to clear the access list";
}
return;
@@ -544,9 +455,9 @@ class CommandCSAccess : public Command
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
else if (is_list && ci->AccessFor(u).HasPriv("ACCESS_LIST"))
has_access = true;
else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
else if (ci->AccessFor(u).HasPriv("ACCESS_CHANGE"))
has_access = true;
else if (is_del)
{
@@ -646,8 +557,6 @@ class CommandCSAccess : public Command
class CommandCSLevels : public Command
{
int levelinfo_maxwidth;
void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
@@ -676,30 +585,23 @@ class CommandCSLevels : public Command
source.Reply(_("Level must be between %d and %d inclusive."), ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
else
{
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
Privilege *p = PrivilegeManager::FindPrivilege(what);
if (p == NULL)
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
else
{
AccessLevels &l = defaultLevels[i];
ci->SetLevel(p->name, level);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, p->name, level));
if (what.equals_ci(l.name))
{
ci->levels[l.priv] = level;
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level));
bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to set " << p->name << " to level " << level;
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "SET " << l.name << " to " << level;
if (level == ACCESS_FOUNDER)
source.Reply(_("Level for %s on channel %s changed to founder only."), l.name.c_str(), ci->name.c_str());
else
source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), l.name.c_str(), ci->name.c_str(), level);
return;
}
if (level == ACCESS_FOUNDER)
source.Reply(_("Level for %s on channel %s changed to founder only."), p->name.c_str(), ci->name.c_str());
else
source.Reply(_("Level for \002%s\002 on channel %s changed to \002%d\002."), p->name.c_str(), ci->name.c_str(), level);
}
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
}
return;
}
void DoDisable(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -710,22 +612,20 @@ class CommandCSLevels : public Command
/* 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.equals_ci("FOUNDER"))
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
Privilege *p = PrivilegeManager::FindPrivilege(what);
if (p != NULL)
{
AccessLevels &l = defaultLevels[i];
ci->SetLevel(p->name, ACCESS_INVALID);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, p->name, ACCESS_INVALID));
if (what.equals_ci(l.name))
{
ci->levels[l.priv] = ACCESS_INVALID;
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, l.priv));
bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to disable " << p->name;
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DISABLE " << l.name;
source.Reply(_("\002%s\002 disabled on channel %s."), l.name.c_str(), ci->name.c_str());
return;
}
source.Reply(_("\002%s\002 disabled on channel %s."), p->name.c_str(), ci->name.c_str());
return;
}
}
source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.owner->nick.c_str());
@@ -736,30 +636,34 @@ class CommandCSLevels : public Command
{
source.Reply(_("Access level settings for channel %s:"), ci->name.c_str());
if (!levelinfo_maxwidth)
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
ListFormatter list;
list.addColumn("Name").addColumn("Level");
int len = l.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
for (unsigned i = 0; i < privs.size(); ++i)
{
AccessLevels &l = defaultLevels[i];
int j = ci->levels[l.priv];
const Privilege &p = privs[i];
int16_t j = ci->GetLevel(p.name);
ListFormatter::ListEntry entry;
entry["Name"] = p.name;
if (j == ACCESS_INVALID)
source.Reply(_(" %-*s (disabled)"), levelinfo_maxwidth, l.name.c_str());
entry["Level"] = "(disabled)";
else if (j == ACCESS_FOUNDER)
source.Reply(_(" %-*s (founder only)"), levelinfo_maxwidth, l.name.c_str());
entry["Level"] = "(founder only)";
else
source.Reply(_(" %-*s %d"), levelinfo_maxwidth, l.name.c_str(), j);
entry["Level"] = stringify(j);
list.addEntry(entry);
}
return;
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
void DoReset(CommandSource &source, ChannelInfo *ci)
@@ -767,17 +671,17 @@ class CommandCSLevels : public Command
User *u = source.u;
reset_levels(ci);
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, "ALL", 0));
bool override = !ci->AccessFor(u).HasPriv(CA_FOUNDER);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "RESET";
bool override = !ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to reset all levels";
source.Reply(_("Access levels for \002%s\002 reset to defaults."), ci->name.c_str());
return;
}
public:
CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4), levelinfo_maxwidth(0)
CommandCSLevels(Module *creator) : Command(creator, "chanserv/levels", 2, 4)
{
this->SetDesc(_("Redefine the meanings of access levels"));
this->SetSyntax(_("\037channel\037 SET \037type\037 \037level\037"));
@@ -806,7 +710,7 @@ class CommandCSLevels : public Command
*/
if (cmd.equals_ci("SET") ? s.empty() : (cmd.substr(0, 3).equals_ci("DIS") ? (what.empty() || !s.empty()) : !what.empty()))
this->OnSyntaxError(source, cmd);
else if (!ci->AccessFor(u).HasPriv(CA_FOUNDER) && !u->HasPriv("chanserv/access/modify"))
else if (!ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else if (cmd.equals_ci("SET"))
this->DoSet(source, ci, params);
@@ -827,20 +731,25 @@ class CommandCSLevels : public Command
if (subcommand.equals_ci("DESC"))
{
source.Reply(_("The following feature/function names are understood."));
if (!levelinfo_maxwidth)
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
{
AccessLevels &l = defaultLevels[i];
int len = l.name.length();
if (len > levelinfo_maxwidth)
levelinfo_maxwidth = len;
}
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
ListFormatter list;
list.addColumn("Name").addColumn("Description");
const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges();
for (unsigned i = 0; i < privs.size(); ++i)
{
AccessLevels &l = defaultLevels[i];
source.Reply(_(" %-*s %s"), levelinfo_maxwidth, l.name.c_str(), translate(source.u, l.desc.c_str()));
const Privilege &p = privs[i];
ListFormatter::ListEntry entry;
entry["Name"] = p.name;
entry["Description"] = translate(source.u, p.desc.c_str());
list.addEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
else
{
@@ -882,50 +791,55 @@ class CSAccess : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&accessprovider);
ModuleManager::RegisterService(&commandcsaccess);
ModuleManager::RegisterService(&commandcslevels);
Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCreateChan, I_OnGroupCheckPriv };
Implementation i[] = { I_OnReload, I_OnCreateChan, I_OnGroupCheckPriv };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
this->OnReload();
try
{
this->OnReload();
}
catch (const ConfigException &ex)
{
throw ModuleException(ex.GetReason());
}
}
void OnReload()
{
defaultLevels.clear();
ConfigReader config;
for (int i = 0; defaultLevels[i].priv != CA_SIZE; ++i)
for (int i = 0; i < config.Enumerate("privilege"); ++i)
{
AccessLevels &l = defaultLevels[i];
const Anope::string &pname = config.ReadValue("privilege", "name", "", i);
const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
if (value.equals_ci("founder"))
l.default_level = ACCESS_FOUNDER;
Privilege *p = PrivilegeManager::FindPrivilege(pname);
if (p == NULL)
continue;
const Anope::string &value = config.ReadValue("privilege", "level", "", i);
if (value.empty())
continue;
else if (value.equals_ci("founder"))
defaultLevels[p->name] = ACCESS_FOUNDER;
else if (value.equals_ci("disabled"))
l.default_level = ACCESS_INVALID;
defaultLevels[p->name] = ACCESS_INVALID;
else
l.default_level = config.ReadInteger("chanserv", l.config_name, 0, false);
defaultLevels[p->name] = config.ReadInteger("privilege", "level", i, false);
}
}
void OnChanRegistered(ChannelInfo *ci)
{
reset_levels(ci);
}
void OnCreateChan(ChannelInfo *ci)
{
reset_levels(ci);
}
EventReturn OnGroupCheckPriv(const AccessGroup *group, ChannelAccess priv)
EventReturn OnGroupCheckPriv(const AccessGroup *group, const Anope::string &priv)
{
if (group->ci == NULL)
return EVENT_CONTINUE;
/* Special case. Allows a level of < 0 to match anyone, and a level of 0 to match anyone identified. */
int16 level = group->ci->levels[priv];
int16_t level = group->ci->GetLevel(priv);
if (level < 0)
return EVENT_ALLOW;
else if (level == 0 && group->nc)
+134 -188
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -46,115 +46,6 @@ static void split_usermask(const Anope::string &mask, Anope::string &nick, Anope
}
}
class AkickListCallback : public NumberList
{
protected:
CommandSource &source;
ChannelInfo *ci;
bool SentHeader;
public:
AkickListCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), source(_source), ci(_ci), SentHeader(false)
{
}
~AkickListCallback()
{
if (!SentHeader)
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
virtual void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
source.Reply(_(" %3d %s (%s)"), index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->reason.empty() ? akick->reason.c_str() : NO_REASON);
}
};
class AkickViewCallback : public AkickListCallback
{
public:
AkickViewCallback(CommandSource &_source, ChannelInfo *_ci, const Anope::string &numlist) : AkickListCallback(_source, _ci, numlist)
{
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
return;
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
DoList(source, ci, Number - 1, ci->GetAkick(Number - 1));
}
static void DoList(CommandSource &source, ChannelInfo *ci, unsigned index, AutoKick *akick)
{
Anope::string timebuf;
if (akick->addtime)
timebuf = do_strftime(akick->addtime);
else
timebuf = UNKNOWN;
source.Reply(CHAN_AKICK_VIEW_FORMAT, index + 1, akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), !akick->creator.empty() ? akick->creator.c_str() : UNKNOWN, timebuf.c_str(), !akick->reason.empty() ? akick->reason.c_str() : _(NO_REASON));
if (akick->last_used)
source.Reply(_(" Last used %s"), do_strftime(akick->last_used).c_str());
}
};
class AkickDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
public:
AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0)
{
}
~AkickDelCallback()
{
User *u = source.u;
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, c, ci) << "DEL on " << Deleted << " users";
if (!Deleted)
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
else if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
return;
++Deleted;
ci->EraseAkick(Number - 1);
}
};
class CommandCSAKick : public Command
{
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -213,7 +104,7 @@ class CommandCSAKick : public Command
AccessGroup nc_access = ci->AccessFor(nc), u_access = ci->AccessFor(u);
Entry entry_mask(CMODE_BEGIN, mask);
if ((ci->AccessFor(u2).HasPriv(CA_FOUNDER) || nc_access >= u_access) && entry_mask.Matches(u2))
if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
{
source.Reply(ACCESS_DENIED);
return;
@@ -260,8 +151,8 @@ class CommandCSAKick : public Command
else
akick = ci->AddAkick(u->nick, mask, reason);
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << ": " << reason;
bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
@@ -287,8 +178,41 @@ class CommandCSAKick : public Command
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickDelCallback list(source, ci, this, mask);
list.Process();
class AkickDelCallback : public NumberList
{
CommandSource &source;
ChannelInfo *ci;
Command *c;
unsigned Deleted;
public:
AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), Deleted(0)
{
}
~AkickDelCallback()
{
bool override = !ci->AccessFor(source.u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source.u, c, ci) << "to delete " << Deleted << (Deleted == 1 ? " entry" : " entries");
if (!Deleted)
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
else if (Deleted == 1)
source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
else
source.Reply(_("Deleted %d entries from %s autokick list."), Deleted, ci->name.c_str());
}
void HandleNumber(unsigned Number)
{
if (!Number || Number > ci->GetAkickCount())
return;
++Deleted;
ci->EraseAkick(Number - 1);
}
}
delcallback(source, ci, this, mask);
delcallback.Process();
}
else
{
@@ -309,8 +233,8 @@ class CommandCSAKick : public Command
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << mask;
bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to delete " << mask;
ci->EraseAkick(i);
@@ -318,30 +242,54 @@ class CommandCSAKick : public Command
}
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
{
User *u = source.u;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "LIST";
if (!ci->GetAkickCount())
{
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickListCallback list(source, ci, mask);
list.Process();
class AkickListCallback : public NumberList
{
ListFormatter &list;
ChannelInfo *ci;
public:
AkickListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
{
}
void HandleNumber(unsigned number)
{
if (!number || number > ci->GetAkickCount())
return;
AutoKick *akick = ci->GetAkick(number - 1);
Anope::string timebuf, lastused;
if (akick->addtime)
timebuf = do_strftime(akick->addtime, NULL, false);
else
timebuf = UNKNOWN;
if (akick->last_used)
lastused = do_strftime(akick->last_used, NULL, false);
else
lastused = UNKNOWN;
ListFormatter::ListEntry entry;
entry["Number"] = stringify(number);
entry["Mask"] = akick->mask;
entry["Creator"] = akick->creator;
entry["Created"] = timebuf;
entry["Last used"] = lastused;
entry["Reason"] = akick->reason;
this->list.addEntry(entry);
}
}
nl_list(list, ci, mask);
nl_list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
{
AutoKick *akick = ci->GetAkick(i);
@@ -354,68 +302,67 @@ class CommandCSAKick : public Command
continue;
}
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
Anope::string timebuf, lastused;
if (akick->addtime)
timebuf = do_strftime(akick->addtime);
else
timebuf = UNKNOWN;
if (akick->last_used)
lastused = do_strftime(akick->last_used);
else
lastused = UNKNOWN;
AkickListCallback::DoList(source, ci, i, akick);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Mask"] = akick->mask;
entry["Creator"] = akick->creator;
entry["Created"] = timebuf;
entry["Last used"] = lastused;
entry["Reason"] = akick->reason;
list.addEntry(entry);
}
if (!SentHeader)
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
if (list.isEmpty())
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("End of autokick list"));
}
}
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
if (!ci->GetAkickCount())
{
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
ListFormatter list;
list.addColumn("Number").addColumn("Mask").addColumn("Reason");
this->ProcessList(source, ci, params, list);
}
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
{
User *u = source.u;
const Anope::string &mask = params.size() > 2 ? params[2] : "";
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "VIEW";
if (!ci->GetAkickCount())
{
source.Reply(_("%s autokick list is empty."), ci->name.c_str());
return;
}
if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
{
AkickViewCallback list(source, ci, mask);
list.Process();
}
else
{
bool SentHeader = false;
for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
{
AutoKick *akick = ci->GetAkick(i);
if (!mask.empty())
{
if (!akick->HasFlag(AK_ISNICK) && !Anope::Match(akick->mask, mask))
continue;
if (akick->HasFlag(AK_ISNICK) && !Anope::Match(akick->nc->display, mask))
continue;
}
if (!SentHeader)
{
SentHeader = true;
source.Reply(_("Autokick list for %s:"), ci->name.c_str());
}
AkickViewCallback::DoList(source, ci, i, akick);
}
if (!SentHeader)
source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
}
ListFormatter list;
list.addColumn("Number").addColumn("Mask").addColumn("Creator").addColumn("Created").addColumn("Last used").addColumn("Reason");
this->ProcessList(source, ci, params, list);
}
void DoEnforce(CommandSource &source, ChannelInfo *ci)
@@ -438,7 +385,7 @@ class CommandCSAKick : public Command
++count;
}
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ENFORCE, affects " << count << " users";
source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
@@ -447,8 +394,8 @@ class CommandCSAKick : public Command
void DoClear(CommandSource &source, ChannelInfo *ci)
{
User *u = source.u;
bool override = !ci->AccessFor(u).HasPriv(CA_AKICK);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
bool override = !ci->AccessFor(u).HasPriv("AKICK");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to clear the akick list";
ci->ClearAkick();
source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
@@ -461,7 +408,7 @@ class CommandCSAKick : public Command
this->SetSyntax(_("\037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]"));
this->SetSyntax(_("\037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}"));
this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\002AKICK \037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
this->SetSyntax(_("\037channel\037 ENFORCE"));
this->SetSyntax(_("\037channel\037 CLEAR"));
}
@@ -483,7 +430,7 @@ class CommandCSAKick : public Command
if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
this->OnSyntaxError(source, cmd);
else if (!ci->AccessFor(u).HasPriv(CA_AKICK) && !u->HasPriv("chanserv/access/modify"))
else if (!ci->AccessFor(u).HasPriv("AKICK") && !u->HasPriv("chanserv/access/modify"))
source.Reply(ACCESS_DENIED);
else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && readonly)
source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
@@ -557,7 +504,6 @@ class CSAKick : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsakick);
}
};
+7 -12
View File
@@ -1,6 +1,6 @@
/* cs_appendtopic.c - Add text to a channels topic
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Based on the original module by SGR <Alex_SGR@ntlworld.com>
@@ -45,6 +45,7 @@ class CommandCSAppendTopic : public Command
CommandCSAppendTopic(Module *creator) : Command(creator, "chanserv/appendtopic", 2, 2)
{
this->SetDesc(_("Add text to a channels topic"));
this->SetSyntax(_("\037channel\037 \037text\037"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -58,7 +59,7 @@ class CommandCSAppendTopic : public Command
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_TOPIC))
else if (!c->ci->AccessFor(u).HasPriv("TOPIC") && !u->HasCommand("chanserv/topic"))
source.Reply(ACCESS_DENIED);
else
{
@@ -77,27 +78,22 @@ class CommandCSAppendTopic : public Command
if (has_topiclock)
c->ci->SetFlag(CI_TOPICLOCK);
bool override = c->ci->AccessFor(u).HasPriv(CA_TOPIC);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, c->ci) << "changed topic to " << topic;
bool override = !c->ci->AccessFor(u).HasPriv("TOPIC");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, c->ci) << "to append: " << topic;
}
return;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: APPENDTOPIC channel text"));
this->SendSyntax(source);
source.Reply(" ");
source.Reply(("This command allows users to append text to a currently set\n"
source.Reply(_("This command allows users to append text to a currently set\n"
"channel topic. When TOPICLOCK is on, the topic is updated and\n"
"the new, updated topic is locked."));
return true;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
source.Reply(_("Syntax: APPENDTOPIC channel text"));
}
};
class CSAppendTopic : public Module
@@ -110,7 +106,6 @@ class CSAppendTopic : public Module
{
this->SetAuthor("SGR");
ModuleManager::RegisterService(&commandcsappendtopic);
}
};
+73 -34
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,7 +19,8 @@ class CommandCSBan : public Command
CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 3)
{
this->SetDesc(_("Bans a selected nick on a channel"));
this->SetSyntax(_("\037#channel\037 \037nick\037 [\037reason\037]"));
this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -37,48 +38,87 @@ class CommandCSBan : public Command
User *u = source.u;
Channel *c = ci->c;
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
User *u2 = finduser(target);
AccessGroup u_access = ci->AccessFor(u), u2_access = ci->AccessFor(u2);
AccessGroup u_access = ci->AccessFor(u);
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
else if (!ci->AccessFor(u).HasPriv(CA_BAN))
source.Reply(ACCESS_DENIED);
else if (!is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
else if (!u_access.HasPriv("BAN"))
source.Reply(ACCESS_DENIED);
/*
* Dont ban/kick the user on channels where he is excepted
* to prevent services <-> server wars.
*/
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
source.Reply(ACCESS_DENIED);
else
else if (u2)
{
Anope::string mask;
get_idealban(ci, u2, mask);
AccessGroup u2_access = ci->AccessFor(u2);
// XXX need a way to detect if someone is overriding
Log(LOG_COMMAND, u, this, ci) << "for " << mask;
c->SetMode(NULL, CMODE_BAN, mask);
/* We still allow host banning while not allowing to kick */
if (!c->FindUser(u2))
return;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
if (u != u2 && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
else if (matches_list(ci->c, u2, CMODE_EXCEPT))
source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
else if (u2->IsProtected())
source.Reply(ACCESS_DENIED);
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
{
Anope::string mask;
get_idealban(ci, u2, mask);
return;
// XXX need a way to detect if someone is overriding
Log(LOG_COMMAND, u, this, ci) << "for " << mask;
c->SetMode(NULL, CMODE_BAN, mask);
/* We still allow host banning while not allowing to kick */
if (!c->FindUser(u2))
return;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv("SIGNKICK")))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
}
else if (u_access.HasPriv("FOUNDER"))
{
Log(LOG_COMMAND, u, this, ci) << "for " << target;
c->SetMode(NULL, CMODE_BAN, target);
int matched = 0, kicked = 0;
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
UserContainer *uc = *it++;
if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
{
++matched;
AccessGroup u2_access = ci->AccessFor(uc->user);
if (u != uc->user && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
continue;
else if (matches_list(ci->c, uc->user, CMODE_EXCEPT))
continue;
else if (uc->user->IsProtected())
continue;
++kicked;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK")))
c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), u->nick.c_str());
else
c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
}
}
if (matched)
source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, target.c_str(), c->name.c_str());
else
source.Reply(_("No users on %s match %s."), c->name.c_str(), target.c_str());
}
else
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -87,8 +127,8 @@ class CommandCSBan : public Command
source.Reply(" ");
source.Reply(_("Bans a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel. Channel founders may ban masks."));
return true;
}
};
@@ -102,7 +142,6 @@ class CSBan : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsban);
}
};
+13 -5
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -31,10 +31,16 @@ class CommandCSClearUsers : public Command
Anope::string modebuf;
if (!c)
{
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
else if (!c->ci)
{
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_FOUNDER))
return;
}
else if (!c->ci->AccessFor(u).HasPriv("FOUNDER") && !u->HasCommand("chanserv/clearusers"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -49,7 +55,10 @@ class CommandCSClearUsers : public Command
c->Kick(NULL, uc->user, "%s", buf.c_str());
}
source.Reply(_("All users have been kicked from \2%s\2."), chan.c_str());
bool override = !c->ci->AccessFor(u).HasPriv("FOUNDER");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, c->ci);
source.Reply(_("All users have been kicked from \002%s\002."), chan.c_str());
return;
}
@@ -58,7 +67,7 @@ class CommandCSClearUsers : public Command
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Tells %s to clear (kick) all users certain settings on a channel."
source.Reply(_("Tells %s to clear (kick) all users on a channel."
" \n"
"By default, limited to those with founder access on the\n"
"channel."), source.owner->nick.c_str());
@@ -76,7 +85,6 @@ class CSClearUsers : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsclearusers);
}
};
+10 -17
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -36,7 +36,7 @@ public:
return;
}
if (!ci->AccessFor(u).HasPriv(CA_SET))
if (!ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -53,12 +53,6 @@ public:
return;
}
if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->HasPriv("chanserv/no-register-limit"))
{
source.Reply(u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : _(CHAN_REACHED_CHANNEL_LIMIT), Config->CSMaxReg);
return;
}
if (what.equals_ci("ALL"))
what.clear();
@@ -107,7 +101,7 @@ public:
FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci));
source.Reply(_("All settings from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("ACCESS"))
{
@@ -127,7 +121,7 @@ public:
target_ci->AddAccess(newaccess);
}
source.Reply(_("All access entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
source.Reply(_("All access entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("AKICK"))
{
@@ -141,7 +135,7 @@ public:
target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
}
source.Reply(_("All akick entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str());
}
else if (what.equals_ci("BADWORDS"))
{
@@ -152,7 +146,7 @@ public:
target_ci->AddBadWord(bw->word, bw->type);
}
source.Reply(_("All badword entries from \002%s\002 have been transferred to \002%s\002"), channel.c_str(), target.c_str());
source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str());
}
else
{
@@ -160,7 +154,7 @@ public:
return;
}
Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name;
Log(LOG_COMMAND, u, this, ci) << "to clone " << (what.empty() ? "everything from it" : what) << " to " << target_ci->name;
return;
}
@@ -169,9 +163,9 @@ public:
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Copies all settings, access, akicks, etc from channel to the\n"
"target channel. If \037what\037 is access, akick, or badwords\n"
"then only the respective settings are transferred.\n"
source.Reply(_("Copies all settings, access, akicks, etc from \002channel\002 to the\n"
"\002target\002 channel. If \037what\037 is \002ACCESS\002, \002AKICK\002, or \002BADWORDS\002\n"
"then only the respective settings are cloned.\n"
"You must be the founder of \037channel\037 and \037target\037."));
return true;
}
@@ -186,7 +180,6 @@ class CSClone : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsclone);
}
};
+4 -5
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -47,7 +47,7 @@ class CommandCSDrop : public Command
return;
}
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER)) && !u->HasCommand("chanserv/drop"))
if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER")) && !u->HasCommand("chanserv/drop"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -56,8 +56,8 @@ class CommandCSDrop : public Command
if (ci->c && ModeManager::FindChannelModeByName(CMODE_REGISTERED))
ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv(CA_FOUNDER));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "none");
bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !ci->AccessFor(u).HasPriv("FOUNDER"));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->display : "none") << ")";
delete ci;
@@ -93,7 +93,6 @@ class CSDrop : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsdrop);
}
};
+2 -3
View File
@@ -1,7 +1,7 @@
/* cs_enforce - Add a /cs ENFORCE command to enforce various set
* options and channelmodes on a channel.
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Included in the Anope module pack since Anope 1.7.9
@@ -129,7 +129,7 @@ class CommandCSEnforce : public Command
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!c->ci)
source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str());
else if (!c->ci->AccessFor(u).HasPriv(CA_AKICK))
else if (!c->ci->AccessFor(u).HasPriv("AKICK"))
source.Reply(ACCESS_DENIED);
else
{
@@ -208,7 +208,6 @@ class CSEnforce : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsenforce);
}
};
+105 -74
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -13,90 +13,151 @@
#include "module.h"
struct EntryMsg
struct EntryMsg : Serializable
{
static unsigned MaxEntries;
ChannelInfo *ci;
Anope::string creator;
Anope::string message;
time_t when;
EntryMsg(const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime)
EntryMsg(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime)
{
this->ci = c;
this->creator = cname;
this->message = cmessage;
this->when = ct;
}
Anope::string creator;
Anope::string message;
time_t when;
Anope::string serialize_name() const
{
return "EntryMsg";
}
serialized_data serialize()
{
serialized_data data;
data["ci"] << this->ci->name;
data["creator"] << this->creator;
data["message"] << this->message;
data["when"].setType(Serialize::DT_INT) << this->when;
return data;
}
static void unserialize(serialized_data &data);
};
unsigned EntryMsg::MaxEntries = 0;
static unsigned MaxEntries = 0;
struct EntryMessageList : std::vector<EntryMsg>, ExtensibleItem
{
};
void EntryMsg::unserialize(serialized_data &data)
{
ChannelInfo *ci = cs_findchan(data["ci"].astr());
if (!ci)
return;
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (messages == NULL)
{
messages = new EntryMessageList();
ci->Extend("cs_entrymsg", messages);
}
messages->push_back(EntryMsg(ci, data["creator"].astr(), data["message"].astr()));
}
class CommandEntryMessage : public Command
{
private:
void DoList(CommandSource &source, ChannelInfo *ci)
{
std::vector<EntryMsg> messages;
if (ci->GetExtRegular("cs_entrymsg", messages))
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (messages == NULL)
{
source.Reply(_("Entry message list for \2%s\2:"), ci->name.c_str());
for (unsigned i = 0; i < messages.size(); ++i)
source.Reply(CHAN_LIST_ENTRY, i + 1, messages[i].message.c_str(), messages[i].creator.c_str(), do_strftime(messages[i].when).c_str());
source.Reply(_("End of entry message list."));
source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
return;
}
else
source.Reply(_("Entry message list for \2%s\2 is empty."), ci->name.c_str());
source.Reply(_("Entry message list for \002%s\002:"), ci->name.c_str());
ListFormatter list;
list.addColumn("Number").addColumn("Creator").addColumn("Created").addColumn("Message");
for (unsigned i = 0; i < messages->size(); ++i)
{
EntryMsg &msg = messages->at(i);
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Creator"] = msg.creator;
entry["Created"] = do_strftime(msg.when);
entry["Message"] = msg.message;
list.addEntry(entry);
}
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("End of entry message list."));
}
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
{
std::vector<EntryMsg> messages;
ci->GetExtRegular("cs_entrymsg", messages);
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (messages == NULL)
{
messages = new EntryMessageList();
ci->Extend("cs_entrymsg", messages);
}
if (EntryMsg::MaxEntries && messages.size() >= EntryMsg::MaxEntries)
source.Reply(_("The entry message list for \2%s\2 is full."), ci->name.c_str());
if (MaxEntries && messages->size() >= MaxEntries)
source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
else
{
messages.push_back(EntryMsg(source.u->nick, message));
ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
source.Reply(_("Entry message added to \2%s\2"), ci->name.c_str());
messages->push_back(EntryMsg(ci, source.u->nick, message));
source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str());
}
}
void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
{
std::vector<EntryMsg> messages;
EntryMessageList *messages = ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (!message.is_pos_number_only())
source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
else if (ci->GetExtRegular("cs_entrymsg", messages))
else if (messages != NULL)
{
try
{
unsigned i = convertTo<unsigned>(message);
if (i > 0 && i <= messages.size())
if (i > 0 && i <= messages->size())
{
messages.erase(messages.begin() + i - 1);
if (!messages.empty())
ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
else
messages->erase(messages->begin() + i - 1);
if (messages->empty())
ci->Shrink("cs_entrymsg");
source.Reply(_("Entry message \2%i\2 for \2%s\2 deleted."), i, ci->name.c_str());
source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str());
}
else
throw ConvertException();
}
catch (const ConvertException &)
{
source.Reply(_("Entry message \2%s\2 not found on channel \2%s\2."), message.c_str(), ci->name.c_str());
source.Reply(_("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
}
}
else
source.Reply(_("Entry message list for \2%s\2 is empty."), ci->name.c_str());
source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
}
void DoClear(CommandSource &source, ChannelInfo *ci)
{
ci->Shrink("cs_entrymsg");
source.Reply(_("Entry messages for \2%s\2 have been cleared."), ci->name.c_str());
source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
}
public:
@@ -117,7 +178,7 @@ class CommandEntryMessage : public Command
return;
}
if (IsFounder(u, ci) || u->HasCommand("chanserv/entrymsg"))
if (IsFounder(u, ci) || u->HasCommand("chanserv/set"))
{
bool success = true;
if (params[1].equals_ci("LIST"))
@@ -139,7 +200,7 @@ class CommandEntryMessage : public Command
this->OnSyntaxError(source, "");
}
if (success)
Log(IsFounder(u, ci) ? LOG_COMMAND : LOG_OVERRIDE, u, this, ci) << params[1];
Log(IsFounder(u, ci) ? LOG_COMMAND : LOG_OVERRIDE, u, this, ci) << " to " << params[1] << " a message";
}
else
source.Reply(ACCESS_DENIED);
@@ -158,17 +219,16 @@ class CommandEntryMessage : public Command
class CSEntryMessage : public Module
{
SerializeType entrymsg_type;
CommandEntryMessage commandentrymsg;
public:
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandentrymsg(this)
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), entrymsg_type("EntryMsg", EntryMsg::unserialize), commandentrymsg(this)
{
this->SetAuthor("Anope");
Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
Implementation i[] = { I_OnReload, I_OnJoinChannel };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
ModuleManager::RegisterService(&commandentrymsg);
this->OnReload();
}
@@ -177,47 +237,18 @@ class CSEntryMessage : public Module
{
if (u && c && c->ci && u->server->IsSynced())
{
std::vector<EntryMsg> messages;
EntryMessageList *messages = c->ci->GetExt<EntryMessageList *>("cs_entrymsg");
if (c->ci->GetExtRegular("cs_entrymsg", messages))
for (unsigned i = 0; i < messages.size(); ++i)
u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
if (messages != NULL)
for (unsigned i = 0; i < messages->size(); ++i)
u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)[i].message.c_str());
}
}
void OnReload()
{
ConfigReader config;
EntryMsg::MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
}
EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, const std::vector<Anope::string> &params)
{
if (key.find("CS_ENTRYMSG_") == 0 && params.size() > 2)
{
Anope::string creator = params[0];
time_t t = params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime;
Anope::string message = params[2];
for (unsigned j = 3; j < params.size(); ++j)
message += " " + params[j];
std::vector<EntryMsg> messages;
ci->GetExtRegular("cs_entrymsg", messages);
messages.push_back(EntryMsg(creator, message, t));
ci->Extend("cs_entrymsg", new ExtensibleItemRegular<std::vector<EntryMsg> >(messages));
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), ChannelInfo *ci)
{
std::vector<EntryMsg> messages;
if (ci->GetExtRegular("cs_entrymsg", messages))
for (unsigned i = 0; i < messages.size(); ++i)
WriteMetadata("CS_ENTRYMSG_" + stringify(i), messages[i].creator + " " + stringify(messages[i].when) + " " + messages[i].message);
MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
}
};
+85 -121
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -13,51 +13,7 @@
#include "module.h"
static struct FlagLevels
{
ChannelAccess priv;
char default_char;
Anope::string config_name;
Anope::string desc;
} flagLevels[] = {
{ CA_ACCESS_CHANGE, 'f', "flag_change", _("Allowed to modify the access list") },
{ CA_ACCESS_LIST, 'l', "flag_list", _("Allowed to view the access list") },
{ CA_AKICK, 'K', "flag_akick", _("Allowed to use AKICK command") },
{ CA_ASSIGN, 's', "flag_assign", _("Allowed to assign/unassign a bot") },
{ CA_AUTOHALFOP, 'H', "flag_autohalfop", _("Automatic mode +h") },
{ CA_AUTOOP, 'O', "flag_autoop", _("Automatic channel operator status") },
{ CA_AUTOOWNER, 'Q', "flag_autoowner", _("Automatic mode +q") },
{ CA_AUTOPROTECT, 'A', "flag_autoprotect", _("Automatic mode +a") },
{ CA_AUTOVOICE, 'V', "flag_autovoice", _("Automatic mode +v") },
{ CA_BADWORDS, 'k', "flag_badwords", _("Allowed to modify channel badwords list") },
{ CA_BAN, 'b', "flag_ban", _("Allowed to use ban users") },
{ CA_FANTASIA, 'c', "flag_fantasia", _("Allowed to use fantasy commands") },
{ CA_FOUNDER, 'F', "flag_founder", _("Allowed to issue commands restricted to channel founders") },
{ CA_GETKEY, 'G', "flag_getkey", _("Allowed to use GETKEY command") },
{ CA_GREET, 'g', "flag_greet", _("Greet message displayed") },
{ CA_HALFOP, 'h', "flag_halfop", _("Allowed to (de)halfop users") },
{ CA_HALFOPME, 'h', "flag_halfopme", _("Allowed to (de)halfop him/herself") },
{ CA_INFO, 'I', "flag_info", _("Allowed to use INFO command with ALL option") },
{ CA_INVITE, 'i', "flag_invite", _("Allowed to use the INVITE command") },
{ CA_KICK, 'k', "flag_kick", _("Allowed to use the KICK command") },
{ CA_MEMO, 'm', "flag_memo", _("Allowed to read channel memos") },
{ CA_MODE, 's', "flag_mode", _("Allowed to change channel modes") },
{ CA_NOKICK, 'N', "flag_nokick", _("Prevents users being kicked by Services") },
{ CA_OPDEOP, 'o', "flag_opdeop", _("Allowed to (de)op users") },
{ CA_OPDEOPME, 'o', "flag_opdeopme", _("Allowed to (de)op him/herself") },
{ CA_OWNER, 'q', "flag_owner", _("Allowed to use (de)owner users") },
{ CA_OWNERME, 'q', "flag_ownerme", _("Allowed to (de)owner him/herself") },
{ CA_PROTECT, 'a', "flag_protect", _("Allowed to (de)protect users") },
{ CA_PROTECTME, 'a', "flag_protectme", _("Allowed to (de)protect him/herself"), },
{ CA_SAY, 'B', "flag_say", _("Allowed to use SAY and ACT commands") },
{ CA_SET, 's', "flag_set", _("Allowed to set channel settings") },
{ CA_SIGNKICK, 'K', "flag_signkick", _("Prevents kicks from being signed") },
{ CA_TOPIC, 't', "flag_topic", _("Allowed to change channel topics") },
{ CA_UNBAN, 'u', "flag_unban", _("Allowed to unban users") },
{ CA_VOICE, 'v', "flag_voice", _("Allowed to (de)voice users") },
{ CA_VOICEME, 'v', "flag_voiceme", _("Allowed to (de)voice him/herself") },
{ CA_SIZE, -1, "", "" }
};
static std::map<Anope::string, char> defaultFlags;
class FlagsChanAccess : public ChanAccess
{
@@ -68,21 +24,11 @@ class FlagsChanAccess : public ChanAccess
{
}
bool Matches(User *u, NickCore *nc)
bool HasPriv(const Anope::string &priv) const
{
if (u && this->mask.find_first_of("!@?*") != Anope::string::npos && (Anope::Match(u->nick, this->mask) || Anope::Match(u->GetMask(), this->mask)))
std::map<Anope::string, char>::iterator it = defaultFlags.find(priv);
if (it != defaultFlags.end() && this->flags.count(it->second) > 0)
return true;
else if (nc && Anope::Match(nc->display, this->mask))
return true;
return false;
}
bool HasPriv(ChannelAccess priv)
{
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
if (flagLevels[i].priv == priv)
return this->flags.count(flagLevels[i].default_char);
return false;
}
@@ -104,13 +50,9 @@ class FlagsChanAccess : public ChanAccess
std::set<char> buffer;
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
{
FlagLevels &l = flagLevels[i];
if (access->HasPriv(l.priv))
buffer.insert(l.default_char);
}
for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
if (access->HasPriv(it->first))
buffer.insert(it->second);
return Anope::string(buffer.begin(), buffer.end());
}
@@ -186,10 +128,9 @@ class CommandCSFlags : public Command
case '*':
if (add == -1)
break;
for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
{
FlagLevels &l = flagLevels[j];
if (!u_access.HasPriv(l.priv))
if (!u_access.HasPriv(it->first))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
@@ -197,20 +138,19 @@ class CommandCSFlags : public Command
continue;
}
if (add == 1)
current_flags.insert(l.default_char);
current_flags.insert(it->second);
else if (add == 0)
current_flags.erase(l.default_char);
current_flags.erase(it->second);
}
break;
default:
if (add == -1)
break;
for (int j = 0; flagLevels[j].priv != CA_SIZE; ++j)
for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
{
FlagLevels &l = flagLevels[j];
if (f != l.default_char)
if (f != it->second)
continue;
else if (!u_access.HasPriv(l.priv))
else if (!u_access.HasPriv(it->first))
{
if (u->HasPriv("chanserv/access/modify"))
override = true;
@@ -234,6 +174,7 @@ class CommandCSFlags : public Command
{
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, current));
ci->EraseAccess(current);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to delete " << mask;
source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str());
}
else
@@ -243,7 +184,7 @@ class CommandCSFlags : public Command
return;
}
service_reference<AccessProvider> provider("access/flags");
service_reference<AccessProvider> provider("AccessProvider", "access/flags");
if (!provider)
return;
FlagsChanAccess *access = debug_cast<FlagsChanAccess *>(provider->Create());
@@ -261,7 +202,7 @@ class CommandCSFlags : public Command
FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "MODIFY " << mask << " with flags " << access->Serialize();
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to modify " << mask << "'s flags to " << access->Serialize();
source.Reply(_("Access for \002%s\002 on %s set to +\002%s\002"), access->mask.c_str(), ci->name.c_str(), access->Serialize().c_str());
return;
@@ -272,45 +213,60 @@ class CommandCSFlags : public Command
const Anope::string &arg = params.size() > 2 ? params[2] : "";
if (!ci->GetAccessCount())
source.Reply(_("%s access list is empty."), ci->name.c_str());
else
{
unsigned total = 0;
source.Reply(_("%s access list is empty."), ci->name.c_str());
return;
}
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
ListFormatter list;
list.addColumn("Number").addColumn("Mask").addColumn("Flags").addColumn("Creator").addColumn("Created");
unsigned count = 0;
for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
{
ChanAccess *access = ci->GetAccess(i);
const Anope::string &flags = FlagsChanAccess::DetermineFlags(access);
if (!arg.empty())
{
ChanAccess *access = ci->GetAccess(i);
const Anope::string &flags = FlagsChanAccess::DetermineFlags(access);
if (!arg.empty())
if (arg[0] == '+')
{
if (arg[0] == '+')
{
bool pass = true;
for (size_t j = 1; j < arg.length(); ++j)
if (flags.find(arg[j]) == Anope::string::npos)
pass = false;
if (pass == false)
continue;
}
else if (!Anope::Match(access->mask, arg))
bool pass = true;
for (size_t j = 1; j < arg.length(); ++j)
if (flags.find(arg[j]) == Anope::string::npos)
pass = false;
if (pass == false)
continue;
}
if (++total == 1)
{
source.Reply(_("Flags list for %s"), ci->name.c_str());
}
source.Reply(_(" %3d %-10s +%-10s [last modified on %s by %s]"), i + 1, access->mask.c_str(), FlagsChanAccess::DetermineFlags(access).c_str(), do_strftime(access->created, source.u->Account(), true).c_str(), access->creator.c_str());
else if (!Anope::Match(access->mask, arg))
continue;
}
if (total == 0)
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else if (total == ci->GetAccessCount())
ListFormatter::ListEntry entry;
++count;
entry["Number"] = stringify(i + 1);
entry["Mask"] = access->mask;
entry["Flags"] = FlagsChanAccess::DetermineFlags(access);
entry["Creator"] = access->creator;
entry["Created"] = do_strftime(access->created, source.u->Account(), true);
list.addEntry(entry);
}
if (list.isEmpty())
source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
else
{
std::vector<Anope::string> replies;
list.Process(replies);
source.Reply(_("Flags list for %s"), ci->name.c_str());
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
if (count == ci->GetAccessCount())
source.Reply(_("End of access list."));
else
source.Reply(_("End of access list - %d/%d entries shown."), total, ci->GetAccessCount());
source.Reply(_("End of access list - %d/%d entries shown."), count, ci->GetAccessCount());
}
}
@@ -329,7 +285,7 @@ class CommandCSFlags : public Command
source.Reply(_("Channel %s access list has been cleared."), ci->name.c_str());
bool override = !IsFounder(u, ci);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "CLEAR";
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to clear the access list";
}
return;
@@ -361,9 +317,9 @@ class CommandCSFlags : public Command
bool has_access = false;
if (u->HasPriv("chanserv/access/modify"))
has_access = true;
else if (is_list && ci->AccessFor(u).HasPriv(CA_ACCESS_LIST))
else if (is_list && ci->AccessFor(u).HasPriv("ACCESS_LIST"))
has_access = true;
else if (ci->AccessFor(u).HasPriv(CA_ACCESS_CHANGE))
else if (ci->AccessFor(u).HasPriv("ACCESS_CHANGE"))
has_access = true;
if (!has_access)
@@ -403,13 +359,17 @@ class CommandCSFlags : public Command
source.Reply(" ");
source.Reply(_("The available flags are:"));
std::multimap<char, FlagLevels *, std::less<ci::string> > levels;
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
levels.insert(std::make_pair(flagLevels[i].default_char, &flagLevels[i]));
for (std::multimap<char, FlagLevels *, std::less<ci::string> >::iterator it = levels.begin(), it_end = levels.end(); it != it_end; ++it)
typedef std::multimap<char, Anope::string, ci::less> reverse_map;
reverse_map reverse;
for (std::map<Anope::string, char>::iterator it = defaultFlags.begin(), it_end = defaultFlags.end(); it != it_end; ++it)
reverse.insert(std::make_pair(it->second, it->first));
for (reverse_map::iterator it = reverse.begin(), it_end = reverse.end(); it != it_end; ++it)
{
FlagLevels *l = it->second;
source.Reply(" %c - %s", l->default_char, translate(source.u->Account(), l->desc.c_str()));
Privilege *p = PrivilegeManager::FindPrivilege(it->second);
if (p == NULL)
continue;
source.Reply(" %c - %s", it->first, translate(source.u->Account(), p->desc.c_str()));
}
return true;
@@ -427,8 +387,6 @@ class CSFlags : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&accessprovider);
ModuleManager::RegisterService(&commandcsflags);
Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, 1);
@@ -439,15 +397,21 @@ class CSFlags : public Module
void OnReload()
{
ConfigReader config;
defaultFlags.clear();
for (int i = 0; flagLevels[i].priv != CA_SIZE; ++i)
for (int i = 0; i < config.Enumerate("privilege"); ++i)
{
FlagLevels &l = flagLevels[i];
const Anope::string &pname = config.ReadValue("privilege", "name", "", i);
const Anope::string &value = config.ReadValue("chanserv", l.config_name, "", 0);
Privilege *p = PrivilegeManager::FindPrivilege(pname);
if (p == NULL)
continue;
const Anope::string &value = config.ReadValue("privilege", "flag", "", i);
if (value.empty())
continue;
l.default_char = value[0];
defaultFlags[p->name] = value[0];
}
}
};
+4 -5
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -35,7 +35,7 @@ class CommandCSGetKey : public Command
}
if (!ci->AccessFor(u).HasPriv(CA_GETKEY) && !u->HasCommand("chanserv/getkey"))
if (!ci->AccessFor(u).HasPriv("GETKEY") && !u->HasCommand("chanserv/getkey"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -44,11 +44,11 @@ class CommandCSGetKey : public Command
Anope::string key;
if (!ci->c || !ci->c->GetParam(CMODE_KEY, key))
{
source.Reply(_("The channel \002%s\002 has no key."), chan.c_str());
source.Reply(_("Channel \002%s\002 has no key."), chan.c_str());
return;
}
bool override = !ci->AccessFor(u).HasPriv(CA_GETKEY);
bool override = !ci->AccessFor(u).HasPriv("GETKEY");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
source.Reply(_("Key for channel \002%s\002 is \002%s\002."), chan.c_str(), key.c_str());
@@ -73,7 +73,6 @@ class CSGetKey : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsgetkey);
}
};
+31 -25
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,14 +15,14 @@
class CommandCSInfo : public Command
{
void CheckOptStr(Anope::string &buf, ChannelInfoFlag opt, const Anope::string &str, ChannelInfo *ci, const NickCore *nc)
void CheckOptStr(Anope::string &buf, ChannelInfoFlag opt, const char *str, ChannelInfo *ci, NickCore *nc)
{
if (ci->HasFlag(opt))
{
if (!buf.empty())
buf += ", ";
buf += str;
buf += translate(nc, str);
}
}
@@ -50,35 +50,37 @@ class CommandCSInfo : public Command
bool show_all = false;
/* Should we show all fields? Only for sadmins and identified users */
if (has_auspex || ci->AccessFor(u).HasPriv(CA_INFO))
if (has_auspex || ci->AccessFor(u).HasPriv("INFO"))
show_all = true;
InfoFormatter info(u);
source.Reply(CHAN_INFO_HEADER, chan.c_str());
if (ci->GetFounder())
source.Reply(_(" Founder: %s"), ci->GetFounder()->display.c_str());
info["Founder"] = ci->GetFounder()->display;
if (show_all && ci->successor)
source.Reply(_(" Successor: %s"), ci->successor->display.c_str());
info["Successor"] = ci->successor->display;
if (!ci->desc.empty())
source.Reply(_(" Description: %s"), ci->desc.c_str());
source.Reply(_(" Registered: %s"), do_strftime(ci->time_registered).c_str());
source.Reply(_(" Last used: %s"), do_strftime(ci->last_used).c_str());
info["Description"] = ci->desc;
info["Registered"] = do_strftime(ci->time_registered);
info["Last used"] = do_strftime(ci->last_used);
ModeLock *secret = ci->GetMLock(CMODE_SECRET);
if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode(CMODE_SECRET)))))
{
source.Reply(_(" Last topic: %s"), ci->last_topic.c_str());
source.Reply(_(" Topic set by: %s"), ci->last_topic_setter.c_str());
info["Last topic"] = ci->last_topic;
info["Topic set by"] = ci->last_topic_setter;
}
if (show_all)
{
source.Reply(_(" Ban type: %d"), ci->bantype);
Anope::string optbuf;
info["Ban type"] = stringify(ci->bantype);
Anope::string optbuf;
CheckOptStr(optbuf, CI_KEEPTOPIC, _("Topic Retention"), ci, u->Account());
CheckOptStr(optbuf, CI_OPNOTICE, _("OP Notice"), ci, u->Account());
CheckOptStr(optbuf, CI_PEACE, _("Peace"), ci, u->Account());
CheckOptStr(optbuf, CI_PRIVATE, _("Private"), ci, u->Account());
CheckOptStr(optbuf, CI_RESTRICTED, _("Restricted Access"), ci, u->Account());
@@ -93,21 +95,26 @@ class CommandCSInfo : public Command
CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, u->Account());
CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, u->Account());
source.Reply(_(" Options: %s"), optbuf.empty() ? _("None") : optbuf.c_str());
source.Reply(_(" Mode lock: %s"), ci->GetMLockAsString(true).c_str());
info["Options"] = optbuf.empty() ? _("None") : optbuf;
info["Mode lock"] = ci->GetMLockAsString(true);
if (!ci->HasFlag(CI_NO_EXPIRE))
source.Reply(_(" Expires on: %s"), do_strftime(ci->last_used + Config->CSExpire).c_str());
info["Expires on"] = do_strftime(ci->last_used + Config->CSExpire);
}
if (ci->HasFlag(CI_SUSPENDED))
{
Anope::string by, reason;
ci->GetExtRegular("suspend_by", by);
ci->GetExtRegular("suspend_reason", reason);
source.Reply(_(" Suspended: [%s] %s"), by.c_str(), !reason.empty() ? reason.c_str() : NO_REASON);
Anope::string *by = ci->GetExt<ExtensibleString *>("suspend_by"), *reason = ci->GetExt<ExtensibleString *>("suspend_reason");
if (by != NULL)
info["Suspended"] = Anope::printf("[%s] %s", by->c_str(), (reason && !reason->empty() ? reason->c_str() : NO_REASON));
}
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, show_all));
FOREACH_MOD(I_OnChanInfo, OnChanInfo(source, ci, info, show_all));
std::vector<Anope::string> replies;
info.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
return;
}
@@ -118,8 +125,8 @@ class CommandCSInfo : public Command
source.Reply(" ");
source.Reply(_("Lists information about the named registered channel,\n"
"including its founder, time of registration, last time\n"
"used, description, and mode lock, if any. If \002ALL\002 is \n"
"specified, the entry message and successor will also \n"
"used, description, and mode lock, if any. If \002ALL\002 is\n"
"specified, the entry message and successor will also\n"
"be displayed."));
return true;
}
@@ -135,7 +142,6 @@ class CSInfo : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsinfo);
}
};
+23 -11
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -18,8 +18,8 @@ class CommandCSInvite : public Command
public:
CommandCSInvite(Module *creator) : Command(creator, "chanserv/invite", 1, 3)
{
this->SetDesc(_("Invites you into a channel"));
this->SetSyntax(_("\037channel\037"));
this->SetDesc(_("Invites you or an optionally specified nick into a channel"));
this->SetSyntax(_("\037channel\037 [\037nick\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -42,7 +42,7 @@ class CommandCSInvite : public Command
return;
}
if (!ci->AccessFor(u).HasPriv(CA_INVITE))
if (!ci->AccessFor(u).HasPriv("INVITE") && !u->HasCommand("chanserv/invite"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -60,15 +60,27 @@ class CommandCSInvite : public Command
}
}
// XXX need a check for override...
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (c->FindUser(u2))
source.Reply(_("You are already in \002%s\002! "), c->name.c_str());
{
if (u2 == u)
source.Reply(_("You are already in \002%s\002!"), c->name.c_str());
else
source.Reply(_("\002%s\002 is already in \002%s\002!"), u2->nick.c_str(), c->name.c_str());
}
else
{
bool override = !ci->AccessFor(u).HasPriv("INVITE");
ircdproto->SendInvite(ci->WhoSends(), chan, u2->nick);
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
if (u2 != u)
{
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "for " << u2->nick;
}
else
{
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci);
}
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
}
return;
@@ -78,7 +90,8 @@ class CommandCSInvite : public Command
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("Tells %s to invite you into the given channel.\n"
source.Reply(_("Tells %s to invite you or an optionally specified\n"
"nick into the given channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
"on the channel."), source.owner->nick.c_str());
@@ -95,7 +108,6 @@ class CSInvite : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsinvite);
}
};
+71 -30
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -20,6 +20,7 @@ class CommandCSKick : public Command
{
this->SetDesc(_("Kicks a selected nick from a channel"));
this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -31,36 +32,77 @@ class CommandCSKick : public Command
User *u = source.u;
ChannelInfo *ci = cs_findchan(params[0]);
Channel *c = findchan(params[0]);
bool is_same = target.equals_ci(u->nick);
User *u2 = is_same ? u : finduser(target);
AccessGroup u_access = ci->AccessFor(u), u2_access = ci->AccessFor(u2);
User *u2 = finduser(target);
if (!c)
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
else if (!ci)
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
else if (!u2)
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
else if (!ci->AccessFor(u).HasPriv(CA_KICK))
source.Reply(ACCESS_DENIED);
else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
else if (u2->IsProtected())
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else
{
// XXX
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !ci->AccessFor(u).HasPriv(CA_SIGNKICK)))
ci->c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
ci->c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
return;
}
return;
else if (!ci)
{
source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
return;
}
AccessGroup u_access = ci->AccessFor(u);
if (!u_access.HasPriv("KICK"))
source.Reply(ACCESS_DENIED);
else if (u2)
{
AccessGroup u2_access = ci->AccessFor(u2);
if (u != u2 && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
source.Reply(ACCESS_DENIED);
else if (u2->IsProtected())
source.Reply(ACCESS_DENIED);
else if (!c->FindUser(u2))
source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
else
{
// XXX
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK")))
c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
}
else if (u_access.HasPriv("FOUNDER"))
{
Log(LOG_COMMAND, u, this, ci) << "for " << target;
int matched = 0, kicked = 0;
for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
UserContainer *uc = *it++;
if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
{
++matched;
AccessGroup u2_access = ci->AccessFor(uc->user);
if (u != uc->user && ci->HasFlag(CI_PEACE) && u2_access >= u_access)
continue;
else if (uc->user->IsProtected())
continue;
++kicked;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK")))
c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), u->nick.c_str());
else
c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
}
}
if (matched)
source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, target.c_str(), c->name.c_str());
else
source.Reply(_("No users on %s match %s."), c->name.c_str(), target.c_str());
}
else
source.Reply(NICK_X_NOT_IN_USE, target.c_str());
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -69,8 +111,8 @@ class CommandCSKick : public Command
source.Reply(" ");
source.Reply(_("Kicks a selected nick on a channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel."));
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel. Channel founders may use masks too."));
return true;
}
};
@@ -84,7 +126,6 @@ class CSKick : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcskick);
}
};
+18 -10
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -71,7 +71,10 @@ class CommandCSList : public Command
Anope::string spattern = "#" + pattern;
source.Reply(LIST_HEADER, pattern.c_str());
source.Reply(_("List of entries matching \002%s\002:"), pattern.c_str());
ListFormatter list;
list.addColumn("Name").addColumn("Description");
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; ++it)
{
@@ -88,22 +91,28 @@ class CommandCSList : public Command
{
if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= Config->CSListMax)
{
char noexpire_char = ' ';
bool isnoexpire = false;
if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE)))
noexpire_char = '!';
isnoexpire = true;
Anope::string buf;
ListFormatter::ListEntry entry;
entry["Name"] = (isnoexpire ? "!" : "") + ci->name;
if (ci->HasFlag(CI_SUSPENDED))
buf = Anope::printf("%-20s [Suspended]", ci->name.c_str());
entry["Description"] = "[Suspended]";
else
buf = Anope::printf("%-20s %s", ci->name.c_str(), !ci->desc.empty() ? ci->desc.c_str() : "");
source.Reply(" %c%s", noexpire_char, buf.c_str());
entry["Description"] = ci->desc;
list.addEntry(entry);
}
++count;
}
}
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
source.Reply(_("End of list - %d/%d matches shown."), nchans > Config->CSListMax ? Config->CSListMax : nchans, nchans);
return;
}
@@ -129,7 +138,6 @@ class CSList : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcslist);
}
};
+219
View File
@@ -0,0 +1,219 @@
/* ChanServ core functions
*
* (C) 2003-2012 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 "memoserv.h"
class CommandCSLog : public Command
{
public:
CommandCSLog(Module *creator) : Command(creator, "chanserv/log", 1, 4)
{
this->SetDesc(_("Configures channel logging settings"));
this->SetSyntax(_("\037channel\037"));
this->SetSyntax(_("\037channel\037 \037command\037 \037method\037 [\037status\037]"));
}
void Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
const Anope::string &channel = params[0];
User *u = source.u;
ChannelInfo *ci = cs_findchan(channel);
if (ci == NULL)
source.Reply(CHAN_X_NOT_REGISTERED, channel.c_str());
else if (!ci->AccessFor(u).HasPriv("SET") && !u->HasPriv("chanserv/set"))
source.Reply(ACCESS_DENIED);
else if (params.size() == 1)
{
if (ci->log_settings.empty())
source.Reply(_("There currently are no logging configurations for %s."), ci->name.c_str());
else
{
ListFormatter list;
list.addColumn("Number").addColumn("Service").addColumn("Command").addColumn("Method").addColumn("");
for (unsigned i = 0; i < ci->log_settings.size(); ++i)
{
LogSetting &log = ci->log_settings[i];
ListFormatter::ListEntry entry;
entry["Number"] = stringify(i + 1);
entry["Service"] = log.command_service;
entry["Command"] = log.command_name;
entry["Method"] = log.method;
entry[""] = log.extra;
list.addEntry(entry);
}
source.Reply(_("Log list for %s:"), ci->name.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
}
else if (params.size() > 2)
{
const Anope::string &command = params[1];
const Anope::string &method = params[2];
const Anope::string &extra = params.size() > 3 ? params[3] : "";
size_t sl = command.find('/');
if (sl == Anope::string::npos)
{
source.Reply(_("%s is not a valid command."), command.c_str());
return;
}
Anope::string service = command.substr(0, sl),
command_name = command.substr(sl + 1);
BotInfo *bi = findbot(service);
if (bi == NULL || bi->commands.count(command_name) == 0)
{
source.Reply(_("%s is not a valid command."), command.c_str());
return;
}
service_reference<Command> c_service("Command", bi->commands[command_name].name);
if (!c_service)
{
source.Reply(_("%s is not a valid command."), command.c_str());
return;
}
if (!method.equals_ci("MESSAGE") && !method.equals_ci("NOTICE") && !method.equals_ci("MEMO"))
{
source.Reply(_("%s is not a valid logging method."), method.c_str());
return;
}
for (unsigned i = 0; i < extra.length(); ++i)
if (ModeManager::GetStatusChar(extra[i]) == 0)
{
source.Reply(_("%c is an unknown status mode."), extra[i]);
return;
}
bool override = !ci->AccessFor(u).HasPriv("SET");
for (unsigned i = ci->log_settings.size(); i > 0; --i)
{
LogSetting &log = ci->log_settings[i - 1];
if (log.service_name == bi->commands[command_name].name && log.method.equals_ci(method))
{
if (log.extra == extra)
{
ci->log_settings.erase(ci->log_settings.begin() + i - 1);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
source.Reply(_("Logging for command %s on %s with log method %s%s%s has been removed."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
}
else
{
log.extra = extra;
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to change logging for " << command << " to method " << method << (extra == "" ? "" : " ") << extra;
source.Reply(_("Logging changed for command %s on %s, now using log method %s%s%s."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
}
return;
}
}
LogSetting log;
log.ci = ci;
log.service_name = bi->commands[command_name].name;
log.command_service = bi->nick;
log.command_name = command_name;
log.method = method;
log.extra = extra;
log.created = Anope::CurTime;
log.creator = u->nick;
ci->log_settings.push_back(log);
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to log " << command << " with method " << method << (extra == "" ? "" : " ") << extra;
source.Reply(_("Logging is now active for command %s on %s, using log method %s%s%s."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str());
}
else
this->OnSyntaxError(source, "");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
this->SendSyntax(source);
source.Reply(" ");
source.Reply(_("The %s command allows users to configure logging settings\n"
"for their channel. If no parameters are given this command\n"
"lists the current logging methods in place for this channel.\n"
" \n"
"Otherwise, \037command\037 must be a command name, and \037method\037\n"
"is one of the following logging methods:\n"
" \n"
" MESSAGE [status], NOTICE [status], MEMO\n"
" \n"
"Which are used to message, notice, and memo the channel respectively.\n"
"With MESSAGE or NOTICE you must have a service bot assigned to and joined\n"
"to your channel. Status may be a channel status such as @ or +.\n"
" \n"
"To remove a logging method use the same syntax as you would to add it.\n"
" \n"
"Example:\n"
" %s #anope chanserv/access MESSAGE @%\n"
" Would message any channel operators whenever someone used the\n"
" ACCESS command on ChanServ on the channel."),
source.command.c_str(), source.command.c_str());
return true;
}
};
class CSLog : public Module
{
CommandCSLog commandcslog;
public:
CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcslog(this)
{
this->SetAuthor("Anope");
Implementation i[] = { I_OnLog };
ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
}
void OnLog(Log *l)
{
if (l->Type != LOG_COMMAND || l->u == NULL || l->c == NULL || l->ci == NULL || !Me || !Me->IsSynced())
return;
for (unsigned i = l->ci->log_settings.size(); i > 0; --i)
{
LogSetting &log = l->ci->log_settings[i - 1];
if (log.service_name == l->c->name)
{
Anope::string buffer = l->u->nick + " used " + log.command_name + " " + l->buf.str();
if (log.method.equals_ci("MESSAGE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
ircdproto->SendPrivmsg(l->ci->bi, log.extra + l->ci->c->name, "%s", buffer.c_str());
else if (log.method.equals_ci("NOTICE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL)
ircdproto->SendNotice(l->ci->bi, log.extra + l->ci->c->name, "%s", buffer.c_str());
else if (log.method.equals_ci("MEMO") && memoserv && l->ci->WhoSends() != NULL)
memoserv->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true);
}
}
}
};
MODULE_INIT(CSLog)
+72 -36
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,25 +15,29 @@
class CommandCSMode : public Command
{
bool CanSet(User *u, ChannelInfo *ci, ChannelModeName mode)
bool CanSet(User *u, ChannelInfo *ci, ChannelMode *cm)
{
switch (mode)
{
case CMODE_OWNER:
return ci->AccessFor(u).HasPriv(CA_OWNER);
case CMODE_PROTECT:
return ci->AccessFor(u).HasPriv(CA_PROTECT);
case CMODE_OP:
return ci->AccessFor(u).HasPriv(CA_OPDEOP);
case CMODE_HALFOP:
return ci->AccessFor(u).HasPriv(CA_HALFOP);
case CMODE_VOICE:
return ci->AccessFor(u).HasPriv(CA_VOICE);
default:
break;
}
if (!u || !ci || !cm || cm->Type != MODE_STATUS)
return false;
return false;
const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" };
const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER };
ChannelModeStatus *cms = debug_cast<ChannelModeStatus *>(cm);
AccessGroup access = ci->AccessFor(u);
unsigned short u_level = 0;
for (int i = 0; !accesses[i].empty(); ++i)
if (access.HasPriv(accesses[i]))
{
ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]);
if (cm2 == NULL || cm2->Type != MODE_STATUS)
continue;
ChannelModeStatus *cms2 = debug_cast<ChannelModeStatus *>(cm2);
if (cms2->Level > u_level)
u_level = cms2->Level;
}
return u_level >= cms->Level;
}
void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
@@ -42,6 +46,8 @@ class CommandCSMode : public Command
const Anope::string &subcommand = params[2];
const Anope::string &param = params.size() > 3 ? params[3] : "";
bool override = !ci->AccessFor(u).HasPriv("MODE");
if (subcommand.equals_ci("ADD") && !param.empty())
{
spacesepstream sep(param);
@@ -64,11 +70,17 @@ class CommandCSMode : public Command
if (adding == -1)
break;
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (!cm || !cm->CanSet(u))
if (!cm)
{
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
break;
}
else if (!cm->CanSet(u))
{
source.Reply(_("You may not (un)lock mode %c."), modes[i]);
break;
}
Anope::string mode_param;
if (((cm->Type == MODE_STATUS || cm->Type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->Type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
@@ -78,6 +90,7 @@ class CommandCSMode : public Command
if (!mode_param.empty())
mode_param = " " + mode_param;
source.Reply(_("%c%c%s locked on %s"), adding ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to lock " << (adding ? '+' : '-') << cm->ModeChar << mode_param;
}
}
}
@@ -107,11 +120,17 @@ class CommandCSMode : public Command
if (adding == -1)
break;
ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
if (!cm || !cm->CanSet(u))
if (!cm)
{
source.Reply(_("Unknown mode character %c ignored."), modes[i]);
break;
}
else if (!cm->CanSet(u))
{
source.Reply(_("You may not (un)lock mode %c."), modes[i]);
break;
}
Anope::string mode_param;
if (!cm->Type == MODE_REGULAR && !sep.GetToken(mode_param))
source.Reply(_("Missing parameter for mode %c."), cm->ModeChar);
@@ -122,6 +141,7 @@ class CommandCSMode : public Command
if (!mode_param.empty())
mode_param = " " + mode_param;
source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str());
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to unlock " << (adding ? '+' : '-') << cm->ModeChar << mode_param;
}
else
source.Reply(_("%c is not locked on %s."), cm->ModeChar, ci->name.c_str());
@@ -138,7 +158,9 @@ class CommandCSMode : public Command
}
else
{
source.Reply(_("Mode locks for %s:"), ci->name.c_str());
ListFormatter list;
list.addColumn("Mode").addColumn("Param").addColumn("Creator").addColumn("Created");
for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
{
const ModeLock &ml = it->second;
@@ -146,11 +168,21 @@ class CommandCSMode : public Command
if (!cm)
continue;
Anope::string modeparam = ml.param;
if (!modeparam.empty())
modeparam = " " + modeparam;
source.Reply(_("%c%c%s, by %s on %s"), ml.set ? '+' : '-', cm->ModeChar, modeparam.c_str(), ml.setter.c_str(), do_strftime(ml.created).c_str());
ListFormatter::ListEntry entry;
entry["Mode"] = Anope::printf("%c%c", ml.set ? '+' : '-', cm->ModeChar);
entry["Param"] = ml.param;
entry["Creator"] = ml.setter;
entry["Created"] = do_strftime(ml.created, source.u->Account(), false);
list.addEntry(entry);
}
source.Reply(_("Mode locks for %s:"), ci->name.c_str());
std::vector<Anope::string> replies;
list.Process(replies);
for (unsigned i = 0; i < replies.size(); ++i)
source.Reply(replies[i]);
}
}
else
@@ -164,7 +196,8 @@ class CommandCSMode : public Command
spacesepstream sep(params.size() > 3 ? params[3] : "");
Anope::string modes = params[2], param;
Log(LOG_COMMAND, u, this, ci) << "to set " << params[2];
bool override = !ci->AccessFor(u).HasPriv("MODE");
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "to set " << params[2];
int adding = -1;
for (size_t i = 0; i < modes.length(); ++i)
@@ -222,7 +255,7 @@ class CommandCSMode : public Command
if (!sep.GetToken(param))
break;
if (!this->CanSet(u, ci, cm->Name))
if (!this->CanSet(u, ci, cm))
{
source.Reply(_("You do not have access to set mode %c."), cm->ModeChar);
break;
@@ -256,15 +289,19 @@ class CommandCSMode : public Command
else
{
User *target = finduser(param);
if (target != NULL)
if (target == NULL)
{
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
source.Reply(NICK_X_NOT_IN_USE, param.c_str());
break;
}
AccessGroup targ_access = ci->AccessFor(target);
if (targ_access > u_access)
{
source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
break;
}
if (adding)
ci->c->SetMode(NULL, cm, param);
else
@@ -311,7 +348,7 @@ class CommandCSMode : public Command
if (!ci || !ci->c)
source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
else if (!ci->AccessFor(u).HasPriv(CA_MODE) && !u->HasCommand("chanserv/mode"))
else if (!ci->AccessFor(u).HasPriv("MODE") && !u->HasPriv("chanserv/set"))
source.Reply(ACCESS_DENIED);
else if (subcommand.equals_ci("LOCK"))
this->DoLock(source, ci, params);
@@ -357,7 +394,6 @@ class CSMode : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsmode);
}
};
+31 -42
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -15,7 +15,7 @@
class CommandModeBase : public Command
{
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself, ChannelInfoFlag notice)
void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.u;
User *u2 = finduser(nick);
@@ -48,8 +48,6 @@ class CommandModeBase : public Command
c->RemoveMode(NULL, cm, u2->nick);
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
ircdproto->SendMessage(ci->WhoSends(), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
}
}
@@ -61,19 +59,18 @@ class CommandModeBase : public Command
* @param chan The channel its being set on
* @param nick The nick the modes being set on
* @param set Is the mode being set or removed
* @param level The acecss level required to set this mode on someone else
* @param level The access level required to set this mode on someone else
* @param levelself The access level required to set this mode on yourself
* @param notice Flag required on a channel to send a notice
*/
void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, ChannelAccess level, ChannelAccess levelself, ChannelInfoFlag notice)
void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself)
{
User *u = source.u;
if (chan.empty())
for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it)
do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself, notice);
do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself);
else
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself, notice);
do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself);
return;
}
@@ -81,7 +78,7 @@ class CommandModeBase : public Command
public:
CommandModeBase(Module *creator, const Anope::string &cname) : Command(creator, cname, 0, 2)
{
this->SetSyntax(_("[\037#channel\037] [\037nick\037]"));
this->SetSyntax(_("[\037channel\037] [\037nick\037]"));
}
};
@@ -97,7 +94,7 @@ class CommandCSOp : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -108,7 +105,7 @@ class CommandCSOp : public CommandModeBase
"it will op you. If channel is not given, it will op you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel."));
return true;
}
@@ -126,7 +123,7 @@ class CommandCSDeOp : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OPDEOP, CA_OPDEOPME, CI_OPNOTICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OPDEOP", "OPDEOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -137,7 +134,7 @@ class CommandCSDeOp : public CommandModeBase
"it will deop you. If channel is not given, it will deop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel.");
return true;
}
@@ -155,7 +152,7 @@ class CommandCSVoice : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_VOICE, CA_VOICEME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -166,8 +163,8 @@ class CommandCSVoice : public CommandModeBase
"it will voice you. If channel is not given, it will voice you\n"
"on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel, or to VOPs or those with level 3 \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel, or to VOPs or those with level 3\n"
"and above for self voicing."));
return true;
}
@@ -185,7 +182,7 @@ class CommandCSDeVoice : public CommandModeBase
{
ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_VOICE, CA_VOICEME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "VOICE", "VOICEME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -196,8 +193,8 @@ class CommandCSDeVoice : public CommandModeBase
"it will devoice you. If channel is not given, it will devoice\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 access \n"
"and above on the channel, or to VOPs or those with level 3 \n"
"By default, limited to AOPs or those with level 5 access\n"
"and above on the channel, or to VOPs or those with level 3\n"
"and above for self devoicing."));
return true;
}
@@ -218,7 +215,7 @@ class CommandCSHalfOp : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -229,8 +226,9 @@ class CommandCSHalfOp : public CommandModeBase
"it will halfop you. If channel is not given, it will halfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access \n"
"and above on the channel, or to HOPs or those with level 4 \n"));
"By default, limited to AOPs and those with level 5 access\n"
"and above on the channel, or to HOPs or those with level 4\n"
"and above for self halfopping."));
return true;
}
};
@@ -250,7 +248,7 @@ class CommandCSDeHalfOp : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_HALFOP, CA_HALFOPME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "HALFOP", "HALFOPME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -261,8 +259,8 @@ class CommandCSDeHalfOp : public CommandModeBase
"it will dehalfop you. If channel is not given, it will dehalfop\n"
"you on every channel.\n"
" \n"
"By default, limited to AOPs and those with level 5 access \n"
"and above on the channel, or to HOPs or those with level 4 \n"
"By default, limited to AOPs and those with level 5 access\n"
"and above on the channel, or to HOPs or those with level 4\n"
"and above for self dehalfopping."));
return true;
}
@@ -283,7 +281,7 @@ class CommandCSProtect : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -294,7 +292,7 @@ class CommandCSProtect : public CommandModeBase
"it will protect you. If channel is not given, it will protect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with \n"
"By default, limited to the founder, or to SOPs or those with\n"
"level 10 and above on the channel for self protecting."));
return true;
}
@@ -315,7 +313,7 @@ class CommandCSDeProtect : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_PROTECT, CA_PROTECTME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "PROTECT", "PROTECTME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -326,7 +324,8 @@ class CommandCSDeProtect : public CommandModeBase
"it will deprotect you. If channel is not given, it will deprotect\n"
"you on every channel.\n"
" \n"
"By default, limited to the founder, or to SOPs or those with \n"));
"By default, limited to the founder, or to SOPs or those with\n"
"level 10 and above on the channel for self deprotecting."));
return true;
}
};
@@ -346,7 +345,7 @@ class CommandCSOwner : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, CA_OWNER, CA_OWNERME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -377,7 +376,7 @@ class CommandCSDeOwner : public CommandModeBase
if (!cm)
return;
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, CA_OWNER, CA_OWNERME, CI_BEGIN);
return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OWNER", "OWNERME");
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
@@ -414,17 +413,7 @@ class CSModes : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsop);
ModuleManager::RegisterService(&commandcsdeop);
ModuleManager::RegisterService(&commandcsvoice);
ModuleManager::RegisterService(&commandcsdevoice);
ModuleManager::RegisterService(&commandcsowner);
ModuleManager::RegisterService(&commandcsdeowner);
ModuleManager::RegisterService(&commandcsprotect);
ModuleManager::RegisterService(&commandcsdeprotect);
ModuleManager::RegisterService(&commandcshalfop);
ModuleManager::RegisterService(&commandcsdehalfop);
}
};
+6 -50
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -54,8 +54,12 @@ class CommandCSRegister : public Command
if (!chdesc.empty())
ci->desc = chdesc;
ci->mode_locks = def_mode_locks;
for (ChannelInfo::ModeList::iterator it = ci->mode_locks.begin(), it_end = ci->mode_locks.end(); it != it_end; ++it)
{
it->second.setter = u->nick;
it->second.ci = ci;
}
if (c && !c->topic.empty())
{
@@ -66,7 +70,6 @@ class CommandCSRegister : public Command
else
ci->last_topic_setter = source.owner->nick;
ci->bi = NULL;
Log(LOG_COMMAND, u, this, ci);
source.Reply(_("Channel \002%s\002 registered under your nickname: %s"), chan.c_str(), u->nick.c_str());
@@ -125,64 +128,17 @@ class CommandCSRegister : public Command
}
};
class ExpireCallback : public CallBack
{
public:
ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
void Tick(time_t)
{
if (!Config->CSExpire || noexpire || readonly)
return;
for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; )
{
ChannelInfo *ci = it->second;
++it;
bool expire = false;
if (ci->HasFlag(CI_SUSPENDED))
{
if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire)
expire = true;
}
else if (!ci->c && Config->CSExpire && Anope::CurTime - ci->last_used >= Config->CSExpire)
expire = true;
if (ci->HasFlag(CI_NO_EXPIRE))
expire = false;
if (expire)
{
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
if (MOD_RESULT == EVENT_STOP)
continue;
Anope::string extra;
if (ci->HasFlag(CI_SUSPENDED))
extra = "suspended ";
Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")";
FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci));
delete ci;
}
}
}
};
class CSRegister : public Module
{
CommandCSRegister commandcsregister;
ExpireCallback ecb;
public:
CSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
commandcsregister(this), ecb(this)
commandcsregister(this)
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsregister);
ModuleManager::Attach(I_OnDelChan, this);
}
+2 -3
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -43,7 +43,7 @@ class CommandCSSASet : public Command
CommandInfo &info = it->second;
if (c_name.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(info.name);
service_reference<Command> command("Command", info.name);
if (command)
{
source.command = it->first;
@@ -67,7 +67,6 @@ class CSSASet : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssaset);
}
};
+2 -3
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -32,7 +32,7 @@ class CommandCSSASetNoexpire : public Command
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -74,7 +74,6 @@ class CSSetNoexpire : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssasetnoexpire);
}
};
+67 -100
View File
@@ -1,6 +1,6 @@
/* cs_seen: provides a seen command by tracking all users
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -19,26 +19,64 @@ enum TypeInfo
NEW, NICK_TO, NICK_FROM, JOIN, PART, QUIT, KICK
};
struct SeenInfo
struct SeenInfo;
typedef Anope::insensitive_map<SeenInfo *> database_map;
database_map database;
struct SeenInfo : Serializable
{
Anope::string nick;
Anope::string vhost;
TypeInfo type;
Anope::string nick2; // for nickchanges and kicks
Anope::string channel; // for join/part/kick
Anope::string message; // for part/kick/quit
time_t last; // the time when the user was last seen
SeenInfo()
{
}
Anope::string serialize_name() const
{
return "SeenInfo";
}
serialized_data serialize()
{
serialized_data data;
data["nick"] << nick;
data["vhost"] << vhost;
data["type"] << type;
data["nick2"] << nick2;
data["channel"] << channel;
data["message"] << message;
data["last"].setType(Serialize::DT_INT) << last;
return data;
}
static void unserialize(serialized_data &data)
{
SeenInfo *s = new SeenInfo();
data["nick"] >> s->nick;
data["vhost"] >> s->vhost;
unsigned int n;
data["type"] >> n;
s->type = static_cast<TypeInfo>(n);
data["nick2"] >> s->nick2;
data["channel"] >> s->channel;
data["message"] >> s->message;
data["last"] >> s->last;
database[s->nick] = s;
}
};
class ModuleConfigClass
{
public:
time_t purgetime;
time_t expiretimeout;
};
ModuleConfigClass ModuleConfig;
typedef Anope::insensitive_map<SeenInfo *> database_map;
database_map database;
static time_t purgetime;
static time_t expiretimeout;
static SeenInfo *FindInfo(const Anope::string &nick)
{
@@ -262,7 +300,7 @@ class DataBasePurger : public CallBack
database_map::iterator cur = it;
++it;
if ((Anope::CurTime - cur->second->last) > ModuleConfig.purgetime)
if ((Anope::CurTime - cur->second->last) > purgetime)
{
Log(LOG_DEBUG) << cur->first << " was last seen " << do_strftime(cur->second->last) << ", purging entry";
delete cur->second;
@@ -275,11 +313,12 @@ class DataBasePurger : public CallBack
class CSSeen : public Module
{
SerializeType seeninfo_type;
CommandSeen commandseen;
CommandOSSeen commandosseen;
DataBasePurger purger;
public:
CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandseen(this), commandosseen(this), purger(this)
CSSeen(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), seeninfo_type("SeenInfo", SeenInfo::unserialize), commandseen(this), commandosseen(this), purger(this)
{
this->SetAuthor("Anope");
@@ -289,50 +328,53 @@ class CSSeen : public Module
I_OnUserQuit,
I_OnJoinChannel,
I_OnPartChannel,
I_OnUserKicked,
I_OnDatabaseRead,
I_OnDatabaseWrite };
I_OnUserKicked };
ModuleManager::Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
ModuleManager::RegisterService(&commandseen);
ModuleManager::RegisterService(&commandosseen);
OnReload();
}
void OnReload()
{
ConfigReader config;
ModuleConfig.purgetime = dotime(config.ReadValue("cs_seen", "purgetime", "30d", 0));
ModuleConfig.expiretimeout = dotime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0));
purgetime = dotime(config.ReadValue("cs_seen", "purgetime", "30d", 0));
expiretimeout = dotime(config.ReadValue("cs_seen", "expiretimeout", "1d", 0));
if (purger.GetSecs() != ModuleConfig.expiretimeout)
purger.SetSecs(ModuleConfig.expiretimeout);
if (purger.GetSecs() != expiretimeout)
purger.SetSecs(expiretimeout);
}
void OnUserConnect(User *u)
{
UpdateUser(u, NEW, u->nick, "", "", "");
}
void OnUserNickChange(User *u, const Anope::string &oldnick)
{
UpdateUser(u, NICK_TO, oldnick, u->nick, "", "");
UpdateUser(u, NICK_FROM, u->nick, oldnick, "", "");
}
void OnUserQuit(User *u, const Anope::string &msg)
{
UpdateUser(u, QUIT, u->nick, "", "", msg);
}
void OnJoinChannel(User *u, Channel *c)
{
UpdateUser(u, JOIN, u->nick, "", c->name, "");
}
void OnPartChannel(User *u, Channel *c, const Anope::string &channel, const Anope::string &msg)
{
UpdateUser(u, PART, u->nick, "", channel, msg);
}
void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &msg)
{
UpdateUser(target, KICK, target->nick, source, c->name, msg);
}
void UpdateUser(const User *u, const TypeInfo Type, const Anope::string &nick, const Anope::string &nick2, const Anope::string &channel, const Anope::string &message)
{
SeenInfo *info = FindInfo(nick);
@@ -341,6 +383,7 @@ class CSSeen : public Module
info = new SeenInfo;
database.insert(std::pair<Anope::string, SeenInfo *>(nick, info));
}
info->nick = nick;
info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost();
info->type = Type;
info->last = Anope::CurTime;
@@ -348,82 +391,6 @@ class CSSeen : public Module
info->channel = channel;
info->message = message;
}
EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
{
if (params[0].equals_ci("SEEN") && (params.size() >= 5))
{
SeenInfo *info = new SeenInfo;
database.insert(std::pair<Anope::string, SeenInfo *>(params[1], info));
info->vhost = params[2];
info->last = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : 0 ;
if (params[4].equals_ci("NEW"))
{
info->type = NEW;
}
else if (params[4].equals_ci("NICK_TO") && params.size() == 6)
{
info->type = NICK_TO;
info->nick2 = params[5];
}
else if (params[4].equals_ci("NICK_FROM") && params.size() == 6)
{
info->type = NICK_FROM;
info->nick2 = params[5];
}
else if (params[4].equals_ci("JOIN") && params.size() == 6)
{
info->type = JOIN;
info->channel = params[5];
}
else if (params[4].equals_ci("PART") && params.size() == 7)
{
info->type = PART;
info->channel = params[5];
info->message = params[6];
}
else if (params[4].equals_ci("QUIT") && params.size() == 6)
{
info->type = QUIT;
info->message = params[5];
}
else if (params[4].equals_ci("KICK") && params.size() == 8)
{
info->type = KICK;
info->nick2 = params[5];
info->channel = params[6];
info->message = params[7];
}
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
void OnDatabaseWrite(void (*Write)(const Anope::string &))
{
for (database_map::iterator it = database.begin(), it_end = database.end(); it != it_end; ++it)
{
std::stringstream buf;
buf << "SEEN " << it->first.c_str() << " " << it->second->vhost << " " << it->second->last << " ";
switch (it->second->type)
{
case NEW:
buf << "NEW"; break;
case NICK_TO:
buf << "NICK_TO " << it->second->nick2; break;
case NICK_FROM:
buf << "NICK_FROM " << it->second->nick2; break;
case JOIN:
buf << "JOIN " << it->second->channel; break;
case PART:
buf << "PART " << it->second->channel << " :" << it->second->message; break;
case QUIT:
buf << "QUIT :" << it->second->message; break;
case KICK:
buf << "KICK " << it->second->nick2 << " " << it->second->channel << " :" << it->second->message; break;
}
Write(buf.str());
}
}
};
MODULE_INIT(CSSeen)
+2 -3
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -43,7 +43,7 @@ class CommandCSSet : public Command
CommandInfo &info = it->second;
if (c_name.find_ci(this_name + " ") == 0)
{
service_reference<Command> command(info.name);
service_reference<Command> command("Command", info.name);
if (command)
{
source.command = it->first;
@@ -67,7 +67,6 @@ class CSSet : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcsset);
}
};
+3 -5
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -32,7 +32,7 @@ class CommandCSSetBanType : public Command
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -40,7 +40,7 @@ class CommandCSSetBanType : public Command
try
{
int16 new_type = convertTo<int16>(params[1]);
int16_t new_type = convertTo<int16_t>(params[1]);
if (new_type < 0 || new_type > 3)
throw ConvertException("Invalid range");
ci->bantype = new_type;
@@ -90,8 +90,6 @@ class CSSetBanType : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetbantype);
ModuleManager::RegisterService(&commandcssasetbantype);
}
};
+2 -4
View File
@@ -1,6 +1,6 @@
/* ChanServ core functions
*
* (C) 2003-2011 Anope Team
* (C) 2003-2012 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
@@ -32,7 +32,7 @@ class CommandCSSetDescription : public Command
return;
}
if (source.permission.empty() && !ci->AccessFor(u).HasPriv(CA_SET))
if (source.permission.empty() && !ci->AccessFor(u).HasPriv("SET"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -81,8 +81,6 @@ class CSSetDescription : public Module
{
this->SetAuthor("Anope");
ModuleManager::RegisterService(&commandcssetdescription);
ModuleManager::RegisterService(&commandcssasetdescription);
}
};

Some files were not shown because too many files have changed in this diff Show More