From 11c2c16835b3e8368be77ccc5b7ddf949021eccd Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Sat, 3 Jul 2010 21:26:00 +0200 Subject: Moved files around as a preliminary for architectural changes. --- Hsbot/Config.hs | 9 - Hsbot/Core.hs | 91 -- Hsbot/Irc/Command.hs | 74 - Hsbot/Irc/Config.hs | 34 - Hsbot/Irc/Core.hs | 177 --- Hsbot/Irc/Message.hs | 73 - Hsbot/Irc/Plugin.hs | 97 -- Hsbot/Irc/Plugin/Core.hs | 66 - Hsbot/Irc/Plugin/Dummy.hs | 27 - Hsbot/Irc/Plugin/Ping.hs | 33 - Hsbot/Irc/Plugin/Quote.hs | 174 --- Hsbot/Irc/Plugin/Utils.hs | 66 - Hsbot/Irc/Server.hs | 35 - Hsbot/Irc/Types.hs | 48 - Hsbot/Irc/doc/rfc2812.txt | 3531 --------------------------------------------- Hsbot/Message.hs | 35 - Hsbot/Plugin.hs | 67 - Hsbot/PluginUtils.hs | 15 - Hsbot/Types.hs | 75 - 19 files changed, 4727 deletions(-) delete mode 100644 Hsbot/Config.hs delete mode 100644 Hsbot/Core.hs delete mode 100644 Hsbot/Irc/Command.hs delete mode 100644 Hsbot/Irc/Config.hs delete mode 100644 Hsbot/Irc/Core.hs delete mode 100644 Hsbot/Irc/Message.hs delete mode 100644 Hsbot/Irc/Plugin.hs delete mode 100644 Hsbot/Irc/Plugin/Core.hs delete mode 100644 Hsbot/Irc/Plugin/Dummy.hs delete mode 100644 Hsbot/Irc/Plugin/Ping.hs delete mode 100644 Hsbot/Irc/Plugin/Quote.hs delete mode 100644 Hsbot/Irc/Plugin/Utils.hs delete mode 100644 Hsbot/Irc/Server.hs delete mode 100644 Hsbot/Irc/Types.hs delete mode 100644 Hsbot/Irc/doc/rfc2812.txt delete mode 100644 Hsbot/Message.hs delete mode 100644 Hsbot/Plugin.hs delete mode 100644 Hsbot/PluginUtils.hs delete mode 100644 Hsbot/Types.hs (limited to 'Hsbot') diff --git a/Hsbot/Config.hs b/Hsbot/Config.hs deleted file mode 100644 index 121cc98..0000000 --- a/Hsbot/Config.hs +++ /dev/null @@ -1,9 +0,0 @@ -module Hsbot.Config - ( BotConfig (..) - ) where - -import Hsbot.Irc.Config - --- | Configuration data type -data BotConfig = IrcBotConfig IrcConfig - diff --git a/Hsbot/Core.hs b/Hsbot/Core.hs deleted file mode 100644 index dad965d..0000000 --- a/Hsbot/Core.hs +++ /dev/null @@ -1,91 +0,0 @@ -module Hsbot.Core - ( hsbot - ) where - -import Control.Concurrent.Chan -import Control.Concurrent.MVar -import Control.Exception -import Control.Monad.State -import qualified Data.Map as M -import Data.Time -import Prelude hiding (catch) -import System.IO() -import System.Posix.Signals - -import Hsbot.Config -import Hsbot.Message -import Hsbot.Plugin -import Hsbot.Types - --- | Bot's main entry point -hsbot :: [BotConfig] -> Maybe String -> IO () -hsbot config txtResumeData= do - let resumeData = case txtResumeData of - Just txtData -> read txtData :: BotResumeData -- TODO : catch exception - Nothing -> M.empty :: BotResumeData - startTime <- case M.lookup "HSBOT" resumeData of - Just hsbotData -> do - case M.lookup "STARTTIME" hsbotData of - Just txtStartTime -> do - let gotStartTime = read txtStartTime :: UTCTime - return gotStartTime - Nothing -> getCurrentTime - Nothing -> getCurrentTime - let resumeData' = M.insert "HSBOT" (M.singleton "STARTTIME" $ show startTime) resumeData - putStrLn "[Hsbot] Opening communication channel... " - chan <- newChan :: IO (Chan BotMsg) - mvar <- newMVar resumeData' :: IO (MVar BotResumeData) - putStrLn "[Hsbot] Installing signal handlers... " - _ <- installHandler sigHUP (Catch $ sigHupHandler chan) Nothing - _ <- installHandler sigTERM (Catch $ sigTermHandler chan) Nothing - putStrLn "[Hsbot] Spawning IrcBot plugins... " - botState <- execStateT spawnPlugins BotState { botStartTime = startTime - , botPlugins = M.empty - , botChan = chan - , botConfig = config - , botResumeData = mvar } - putStrLn "[Hsbot] Entering main loop... " - (status, botState') <- runLoop botState - putStrLn "[Hsbot] Killing active plugins... " - newResumeData <- takeMVar mvar - evalStateT (mapM_ killPlugin $ M.keys newResumeData) botState' - if status == BotReboot - then hsbot config (Just $ show newResumeData) -- TODO : exec on the hsbot launcher with the reload string - else return () - where - runLoop :: BotState -> IO (BotStatus, BotState) - runLoop botState = do - (status, botState') <- (runStateT botCore botState) `catches` [ Handler (\ (_ :: IOException) -> return (BotExit, botState)) - , Handler (\ (_ :: AsyncException) -> return (BotExit, botState)) ] - case status of - BotContinue -> runLoop botState' - _ -> return (status, botState') - --- | Run the bot main loop -botCore :: Bot (BotStatus) -botCore = do - chan <- gets botChan - msg <- liftIO $ readChan chan - case msg of - IntMsg intMsg -> processInternalMessage intMsg - UpdMsg updMsg -> processUpdateMessage updMsg - RebMsg rebMsg -> processRebootMessage rebMsg - ExiMsg exiMsg -> processExitMessage exiMsg - --- | Process an update command -processUpdateMessage :: ResumeMsg -> Bot (BotStatus) -processUpdateMessage msg = do - resumeData <- gets botResumeData - let from = resMsgFrom msg - stuff = resMsgData msg - liftIO $ modifyMVar_ resumeData (\oldData -> return $ M.insert from stuff oldData) - return BotContinue - --- | signals handlers -sigHupHandler :: Chan BotMsg -> IO () -sigHupHandler chan = writeChan chan $ RebMsg RebootMsg { rebMsgFrom = "HUP handler" } - --- | signals handlers -sigTermHandler :: Chan BotMsg -> IO () -sigTermHandler chan = writeChan chan $ ExiMsg ExitMsg { exiMsgFrom = "TERM handler" } - diff --git a/Hsbot/Irc/Command.hs b/Hsbot/Irc/Command.hs deleted file mode 100644 index 51c2187..0000000 --- a/Hsbot/Irc/Command.hs +++ /dev/null @@ -1,74 +0,0 @@ -module Hsbot.Irc.Command - ( processInternalCommand - , registerCommand - , unregisterCommand - ) where - -import Control.Monad.State -import qualified Data.List as L -import qualified Data.Map as M -import Data.Maybe - -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin -import Hsbot.Irc.Types -import Hsbot.Types - --- | Registers a plugin's command -registerCommand :: String -> String -> IrcBot () -registerCommand cmd pluginName' = do - ircBot <- get - let cmds = ircBotCommands ircBot - plugins = ircBotPlugins ircBot - case M.lookup pluginName' plugins of - Just _ -> let pluginNames = pluginName' : fromMaybe [] (M.lookup cmd cmds) -- TODO : remove/check for duplicates ? - newCmds = M.insert cmd pluginNames cmds - in put $ ircBot { ircBotCommands = newCmds } - Nothing -> return () - --- | Unregisters a plugin's command -unregisterCommand :: String -> String -> IrcBot () -unregisterCommand cmd pluginName' = do - ircBot <- get - let cmds = ircBotCommands ircBot - newCmds = M.adjust (L.delete pluginName') cmd cmds - put $ ircBot { ircBotCommands = newCmds } - --- | Processes an internal command -processInternalCommand :: IrcBotMsg -> IrcBot (BotStatus) -processInternalCommand (IntIrcCmd ircCmd) - | ircCmdTo ircCmd == "CORE" = processCoreCommand ircCmd - | otherwise = do - plugins <- gets ircBotPlugins - case M.lookup (ircCmdTo ircCmd) plugins of - Just (plugin, _, _) -> sendToPlugin (IntIrcCmd ircCmd) plugin - Nothing -> return () - return BotContinue -processInternalCommand _ = return (BotContinue) - --- | Processes a core command -processCoreCommand :: IrcCmd -> IrcBot (BotStatus) -processCoreCommand ircCmd = do - let command' = ircCmdCmd ircCmd - originalRequest = ircCmdBotMsg ircCmd - case command' of - "LIST" -> listPlugins originalRequest (ircCmdFrom ircCmd) - "LOAD" -> loadIrcPlugin $ ircCmdMsg ircCmd - "REGISTER" -> registerCommand (ircCmdMsg ircCmd) (ircCmdFrom ircCmd) - "UNLOAD" -> unloadIrcPlugin $ ircCmdMsg ircCmd - "UNREGISTER" -> unregisterCommand (ircCmdMsg ircCmd) (ircCmdFrom ircCmd) - "UPDATE" -> processUpdateCommand ircCmd - _ -> return () - if command' == "REBOOT" - then return BotReboot - else return BotContinue - --- | Process an update command -processUpdateCommand :: IrcCmd -> IrcBot () -processUpdateCommand ircCmd = do - ircbot <- get - let oldData = ircBotResumeData ircbot - from = ircCmdFrom ircCmd - stuff = ircCmdMsg ircCmd - put $ ircbot { ircBotResumeData = M.insert from stuff oldData } - diff --git a/Hsbot/Irc/Config.hs b/Hsbot/Irc/Config.hs deleted file mode 100644 index 0d1e5a2..0000000 --- a/Hsbot/Irc/Config.hs +++ /dev/null @@ -1,34 +0,0 @@ -module Hsbot.Irc.Config - ( IrcConfig(..) - , ircDefaultConfig - ) where - -import Network - --- | Configuration data type -data IrcConfig = IrcConfig - { ircConfigName :: String -- The configuration name - , ircConfigAddress :: String -- the server's address - , ircConfigPort :: PortID -- the server's port - , ircConfigChannels :: [String] -- the Channels to join on start - , ircConfigNickname :: String -- the hsbot's nickname - , ircConfigPassword :: String -- the hsbot's password, optional - , ircConfigRealname :: String -- the hsbot's real name, optional - , ircConfigCommandPrefix :: Char -- the prefix the ircbot will recognize as commands - , ircConfigPlugins :: [String] -- the ircPlugins to load - } - --- | User configuration -ircDefaultConfig :: IrcConfig -ircDefaultConfig = IrcConfig - { ircConfigName = "irc-alocalhost" - , ircConfigAddress = "localhost" - , ircConfigPort = PortNumber 6667 - , ircConfigChannels = ["#hsbot"] - , ircConfigNickname = "hsbot" - , ircConfigPassword = "" - , ircConfigRealname = "The One True bot, with it's haskell soul." - , ircConfigCommandPrefix = '@' - , ircConfigPlugins = ["Ping"] - } - diff --git a/Hsbot/Irc/Core.hs b/Hsbot/Irc/Core.hs deleted file mode 100644 index d65e975..0000000 --- a/Hsbot/Irc/Core.hs +++ /dev/null @@ -1,177 +0,0 @@ -module Hsbot.Irc.Core - ( startIrcbot - ) where - -import Control.Concurrent -import Control.Exception (AsyncException, Handler (..), IOException, catch, catches) -import Control.Monad.State -import qualified Data.Map as M -import Data.Maybe (fromMaybe) -import Network -import Prelude hiding (catch) -import System.IO -import System.Posix.IO (fdToHandle, handleToFd) -import System.Posix.Types (Fd) - -import Hsbot.Irc.Command -import Hsbot.Irc.Config -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin -import Hsbot.Irc.Server -import Hsbot.Irc.Types -import Hsbot.Types - --- | IrcBot's main entry point -startIrcbot :: IrcConfig -> Chan BotMsg -> Chan BotMsg -> Maybe String -> IO () -startIrcbot config masterChan myChan txtResumeData = do - let resumeData = case txtResumeData of - Just txtData -> read txtData :: ResumeData -- TODO : catch exception - Nothing -> M.empty :: ResumeData - print resumeData - putStrLn "[IrcBot] Opening communication channel... " - chan <- newChan :: IO (Chan IrcBotMsg) - handle <- case M.lookup "HANDLE" resumeData of - Just txtFd -> do - let fd = read txtFd :: Fd - fdToHandle fd - Nothing -> do - putStrLn $ concat ["[IrcBot] Connecting to ", ircConfigAddress config, "... "] - handle <- connectTo (ircConfigAddress config) (ircConfigPort config) - hSetBuffering handle NoBuffering - hSetEncoding handle utf8 - return handle - fd <- handleToFd handle - putStrLn "[IrcBot] Spawning reader threads..." - myOwnThreadId <- myThreadId - readerThreadId <- forkIO $ ircBotReader handle chan myOwnThreadId - masterReaderThreadId <- forkIO $ ircBotMasterReader myChan chan - putStrLn "[IrcBot] Initializing server connection..." - let ircServerState = IrcServerState { ircServerId = ircConfigAddress config - , ircServerChannels = [] - , ircServerNickname = ircConfigNickname config - , ircServerCommandPrefix = ircConfigCommandPrefix config - , ircServerChan = chan } - ircBotState = IrcBotState { ircBotPlugins = M.empty - , ircBotCommands = M.empty - , ircBotChan = chan - , ircBotMasterChan = masterChan - , ircBotServerState = ircServerState - , ircBotHandle = handle - , ircBotConfig = config - , ircBotResumeData = M.singleton "HANDLE" (show fd) } - ircBotState' <- execStateT (initBotServerConnection config) ircBotState - putStrLn "[IrcBot] Spawning plugins..." - ircBotState'' <- execStateT spawnIrcPlugins ircBotState' - putStrLn "[IrcBot] Entering Core loop... " - ircBotState''' <- (execStateT ircBotLoop ircBotState'') `catches` [ Handler (\ (_ :: IOException) -> return (ircBotState'')) - , Handler (\ (_ :: AsyncException) -> return (ircBotState'')) ] - putStrLn "[IrcBot] Killing reader threads..." - killThread readerThreadId - killThread masterReaderThreadId - putStrLn "[IrcBot] Killing active plugins... " - let resumeData' = ircBotResumeData ircBotState''' - ircPlugins = read (fromMaybe [] (M.lookup "PLUGINS" resumeData')) :: [String] - evalStateT (mapM_ killIrcPlugin ircPlugins) ircBotState''' - return () - ---resumeIrcBot ---resumeIrcBot - --- | Runs the IrcBot's reader loop -ircBotReader :: Handle -> Chan IrcBotMsg -> ThreadId -> IO () -ircBotReader handle chan fatherThreadId = forever $ do - str <- (hGetLine handle) `catch` handleIOException - let msg = parseIrcMsg str - case msg of - Right msg' -> writeChan chan (InIrcMsg msg') - _ -> return () - where - handleIOException :: IOException -> IO (String) - handleIOException ioException = do - throwTo fatherThreadId ioException - myId <- myThreadId - killThread myId - return "" - --- | Reads the Master's chan -ircBotMasterReader :: Chan BotMsg -> Chan IrcBotMsg -> IO () -ircBotMasterReader masterChan _ = forever $ do - _ <- readChan masterChan - return () - -- TODO : handle botMsg - --- | Initialize the bot's server connection -initBotServerConnection :: IrcConfig -> IrcBot () -initBotServerConnection config = do - ircBot <- get - let ircServerState = ircBotServerState ircBot - ircServerState' <- execStateT (initServerConnection config) ircServerState - put $ ircBot { ircBotServerState = ircServerState' } - --- | Run the IrcBot's main loop -ircBotLoop :: IrcBot () -ircBotLoop = forever $ do - chan <- gets ircBotChan - msg <- liftIO $ readChan chan - case msg of - InIrcMsg inIrcMsg -> dispatchMessage $ InIrcMsg inIrcMsg - OutIrcMsg outIrcMsg -> sendThisMessage outIrcMsg - IntIrcCmd intIrcCmd -> do - reboot <- processInternalCommand $ IntIrcCmd intIrcCmd - reportUpdate - if reboot == BotReboot - then processRebootCommand - else return () - where - sendThisMessage :: IrcMsg -> IrcBot () - sendThisMessage outputMsg = do - let str = serializeIrcMsg outputMsg - handle <- gets ircBotHandle - liftIO $ hPutStr handle (str ++ "\r\n") - --- | Dispatches an input message -dispatchMessage :: IrcBotMsg -> IrcBot () -dispatchMessage (InIrcMsg inIrcMsg) = do - config <- gets ircBotConfig - plugins <- gets ircBotPlugins - cmds <- gets ircBotCommands - if (isPluginCommand config) - then - let key = tail . head $ words getMsgContent - pluginNames = fromMaybe [] $ M.lookup key cmds - plugins' = fromMaybe [] $ mapM (flip M.lookup plugins) pluginNames - in mapM_ (sendRunCommand (tail getMsgContent) . first) plugins' - else - mapM_ (sendToPlugin (InIrcMsg inIrcMsg) . first) (M.elems plugins) - where - isPluginCommand :: IrcConfig -> Bool - isPluginCommand config = - and [ ircMsgCommand inIrcMsg == "PRIVMSG" - , (head getMsgContent) == ircConfigCommandPrefix config ] - sendRunCommand :: String -> IrcPluginState -> IrcBot () - sendRunCommand cmd plugin = sendToPlugin (IntIrcCmd $ IrcCmd "RUN" "CORE" (ircPluginName plugin) cmd inIrcMsg) plugin - getMsgContent :: String - getMsgContent = unwords . tail $ ircMsgParameters inIrcMsg -dispatchMessage _ = return () - --- | Reports an update to the master bot -reportUpdate :: IrcBot () -reportUpdate = do - ircbot <- get - let masterChan = ircBotMasterChan ircbot - msg = UpdMsg $ ResMsg { resMsgFrom = ircConfigName $ ircBotConfig ircbot - , resMsgData = ircBotResumeData ircbot } - liftIO $ writeChan masterChan msg - --- | Process a reboot command -processRebootCommand :: IrcBot () -processRebootCommand = do - ircbot <- get - let masterChan = ircBotMasterChan ircbot - msg = IntMsg $ Msg { msgType = "REBOOT" - , msgFrom = ircConfigName $ ircBotConfig ircbot - , msgTo = "CORE" - , msgStuff = show $ ircBotResumeData ircbot - } - liftIO $ writeChan masterChan msg - diff --git a/Hsbot/Irc/Message.hs b/Hsbot/Irc/Message.hs deleted file mode 100644 index e92a9d0..0000000 --- a/Hsbot/Irc/Message.hs +++ /dev/null @@ -1,73 +0,0 @@ -module Hsbot.Irc.Message - ( IrcBotMsg (..) - , IrcCmd (..) - , IrcMsg (..) - , emptyIrcMsg - , parseIrcMsg - , serializeIrcMsg - ) where - -import Control.Monad.Identity -import Text.Parsec - --- | An IRC message -data IrcMsg = IrcMsg - { ircMsgPrefix :: Maybe String -- the message prefix - , ircMsgCommand :: String -- the message command - , ircMsgParameters :: [String] -- the message parameters - } deriving (Show) - -emptyIrcMsg :: IrcMsg -emptyIrcMsg = IrcMsg Nothing "" [] - --- | An internal command -data IrcCmd = IrcCmd - { ircCmdCmd :: String -- the internal command - , ircCmdFrom :: String -- who issues it - , ircCmdTo :: String -- who it is destinated to - , ircCmdMsg :: String -- the message to be transfered - , ircCmdBotMsg :: IrcMsg -- An IrcMsg attached to the command - } deriving (Show) - -data IrcBotMsg = InIrcMsg IrcMsg | OutIrcMsg IrcMsg | IntIrcCmd IrcCmd deriving (Show) - --- | Parses an IrcInput -parseIrcMsg :: String -> Either ParseError IrcMsg -parseIrcMsg line = parse pMsg "" line - -pMsg :: ParsecT String u Identity IrcMsg -pMsg = do - pfx <- optionMaybe pPrefix - cmd <- pCommand - params <- many (char ' ' >> (pLongParam <|> pShortParam)) - _ <- char '\r' - --eof - return $ IrcMsg pfx cmd params - -pPrefix :: ParsecT String u Identity [Char] -pPrefix = do - _ <- char ':' - pfx <- many1 (noneOf " ") - _ <- space - return pfx - -pCommand :: ParsecT String u Identity [Char] -pCommand = count 3 digit <|> many1 upper - -pLongParam :: ParsecT String u Identity [Char] -pLongParam = char ':' >> (many1 (noneOf "\r")) - -pShortParam :: ParsecT String u Identity [Char] -pShortParam = many1 (noneOf " \r") - --- | Serialize an IRC message to a string. -serializeIrcMsg :: IrcMsg -> String -serializeIrcMsg (IrcMsg pfx cmd params) = pfxStr ++ cmd ++ paramStr - where pfxStr = case pfx of - Nothing -> "" - Just pfx' -> ":" ++ pfx' ++ " " - paramStr = concat (map paramToStr (init params) - ++ [lastParamToStr (last params)]) - paramToStr p = " " ++ p - lastParamToStr p = " :" ++ p - diff --git a/Hsbot/Irc/Plugin.hs b/Hsbot/Irc/Plugin.hs deleted file mode 100644 index 2c8e84b..0000000 --- a/Hsbot/Irc/Plugin.hs +++ /dev/null @@ -1,97 +0,0 @@ -module Hsbot.Irc.Plugin - ( IrcPlugin - , IrcPluginState (..) - , killIrcPlugin - , listPlugins - , loadIrcPlugin - , sendToPlugin - , spawnIrcPlugins - , unloadIrcPlugin - ) where - -import Control.Concurrent -import Control.Concurrent.Chan () -import Control.Exception -import Control.Monad.State -import qualified Data.Map as M - -import Hsbot.Irc.Config -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Core -import Hsbot.Irc.Plugin.Dummy -import Hsbot.Irc.Plugin.Ping -import Hsbot.Irc.Plugin.Quote -import Hsbot.Irc.Plugin.Utils -import Hsbot.Irc.Types - --- | Sends a msg to a plugin -sendToPlugin :: IrcBotMsg -> IrcPluginState -> IrcBot () -sendToPlugin ircBotMsg plugin = do - liftIO $ writeChan (ircPluginChan plugin) ircBotMsg - --- | spawns IrcPlugins -spawnIrcPlugins :: IrcBot () -spawnIrcPlugins = do - config <- gets ircBotConfig - mapM_ (loadIrcPlugin) (ircConfigPlugins config) - --- | loads an ircbot plugin -loadIrcPlugin :: String -> IrcBot () -loadIrcPlugin pluginName = do - ircbot <- get - let masterChan = ircBotChan ircbot - pluginChan <- liftIO (newChan :: IO (Chan IrcBotMsg)) - let entryPoint = case pluginName of - "Core" -> ircBotPluginCore - "Ping" -> ircBotPluginPing - "Quote" -> ircBotPluginQuote - _ -> ircBotPluginDummy - let oldPlugins = ircBotPlugins ircbot - oldResumeData = ircBotResumeData ircbot - -- We check for unicity - case M.lookup pluginName oldPlugins of - Just _ -> return () - Nothing -> do - mvar <- liftIO newEmptyMVar - threadId <- liftIO . forkIO $ finally (entryPoint pluginChan masterChan) (putMVar mvar ()) - let plugin = IrcPluginState { ircPluginName = pluginName - , ircPluginChan = pluginChan - , ircPluginMasterChan = masterChan } - newPlugins = M.insert pluginName (plugin, mvar, threadId) oldPlugins - newResumeData = M.insert "PLUGINS" (show $ M.keys newPlugins) oldResumeData - put $ ircbot { ircBotPlugins = newPlugins - , ircBotResumeData = newResumeData } - --- | Sends a list of loaded plugins -listPlugins :: IrcMsg -> String -> IrcBot () -listPlugins originalRequest dest = do - plugins <- gets ircBotPlugins - let listing = unwords $ M.keys plugins - case M.lookup dest plugins of - Just (plugin, _, _) -> sendToPlugin (IntIrcCmd $ IrcCmd "ANSWER" "CORE" dest listing originalRequest) plugin - Nothing -> return () - --- | Unloads a plugin -unloadIrcPlugin :: String -> IrcBot () -unloadIrcPlugin name = do - killIrcPlugin name - ircbot <- get - let oldResumeData = ircBotResumeData ircbot - newPlugins = M.keys $ ircBotPlugins ircbot - newResumeData = M.insert "PLUGINS" (show newPlugins) oldResumeData - put $ ircbot { ircBotResumeData = newResumeData } - --- | kills a plugin -killIrcPlugin :: String -> IrcBot () -killIrcPlugin name = do - ircbot <- get - let oldPlugins = ircBotPlugins ircbot - -- We check if the plugin exists - case M.lookup name oldPlugins of - Just (_, mvar, threadId) -> do - let newPlugins = M.delete name oldPlugins - liftIO $ throwTo threadId UserInterrupt - put $ ircbot { ircBotPlugins = newPlugins } - liftIO $ takeMVar mvar - Nothing -> return () - diff --git a/Hsbot/Irc/Plugin/Core.hs b/Hsbot/Irc/Plugin/Core.hs deleted file mode 100644 index 114ced8..0000000 --- a/Hsbot/Irc/Plugin/Core.hs +++ /dev/null @@ -1,66 +0,0 @@ -module Hsbot.Irc.Plugin.Core - ( ircBotPluginCore - ) where - -import Control.Concurrent (Chan) -import Control.Exception -import Control.Monad.State -import Prelude hiding (catch) - -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Utils - --- | The plugin's main entry point -ircBotPluginCore :: Chan IrcBotMsg -> Chan IrcBotMsg -> IO () -ircBotPluginCore myChan masterChan = do - let plugin = IrcPluginState { ircPluginName = "Core" - , ircPluginChan = myChan - , ircPluginMasterChan = masterChan } - evalStateT (mapM_ sendRegisterCommand ["list", "load", "reload", "unload", "reboot"]) plugin - plugin' <- (execStateT run plugin) `catch` (\(_ :: AsyncException) -> return plugin) - evalStateT (mapM_ sendUnregisterCommand ["list", "load", "reload", "unload", "reboot"]) plugin' - --- | The IrcPlugin monad main function -run :: IrcPlugin () -run = forever $ do - msg <- readMsg - eval msg - where - eval :: IrcBotMsg -> IrcPlugin () - eval (IntIrcCmd intCmd) = do - let request = ircCmdBotMsg intCmd - case ircCmdCmd intCmd of - "RUN" -> let stuff = words $ ircCmdMsg intCmd - in case head stuff of - "list" -> listPlugins request - "load" -> loadPlugin $ tail stuff - "reload" -> reloadPlugin $ tail stuff - "unload" -> unloadPlugin $ tail stuff - "reboot" -> rebootBot $ tail stuff - _ -> return () -- TODO : help message - "ANSWER" -> let stuff = ircCmdMsg intCmd - in answerMsg request ("Loaded plugins : " ++ stuff) - _ -> return () - eval _ = return () - --- | The list command -listPlugins :: IrcMsg -> IrcPlugin () -listPlugins request = do - sendCommandWithRequest "LIST" "CORE" (unwords []) request - --- | The load command -loadPlugin :: [String] -> IrcPlugin () -loadPlugin pluginNames = mapM_ (sendCommand "LOAD" "CORE") pluginNames - --- | The reload command -reloadPlugin :: [String] -> IrcPlugin () -reloadPlugin pluginNames = mapM_ (sendCommand "RELOAD" "CORE") pluginNames - --- | The unload command -unloadPlugin :: [String] -> IrcPlugin () -unloadPlugin pluginNames = mapM_ (sendCommand "UNLOAD" "CORE") pluginNames - --- | The reboot command -rebootBot :: [String] -> IrcPlugin () -rebootBot stuff = sendCommand "REBOOT" "CORE" $ unwords stuff - diff --git a/Hsbot/Irc/Plugin/Dummy.hs b/Hsbot/Irc/Plugin/Dummy.hs deleted file mode 100644 index 4e10644..0000000 --- a/Hsbot/Irc/Plugin/Dummy.hs +++ /dev/null @@ -1,27 +0,0 @@ -module Hsbot.Irc.Plugin.Dummy - ( ircBotPluginDummy - ) where - -import Control.Concurrent.Chan -import Control.Exception -import Control.Monad.State -import Prelude hiding (catch) - -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Utils - --- | The plugin's main entry point -ircBotPluginDummy :: Chan IrcBotMsg -> Chan IrcBotMsg -> IO () -ircBotPluginDummy myChan masterChan = do - let plugin = IrcPluginState { ircPluginName = "Dummy" - , ircPluginChan = myChan - , ircPluginMasterChan = masterChan } - _ <- (execStateT run plugin) `catch` (\(_ :: AsyncException) -> return plugin) - return () - --- | The IrcPlugin monad main function -run :: IrcPlugin () -run = forever $ do - _ <- readMsg - return () - diff --git a/Hsbot/Irc/Plugin/Ping.hs b/Hsbot/Irc/Plugin/Ping.hs deleted file mode 100644 index 57418b3..0000000 --- a/Hsbot/Irc/Plugin/Ping.hs +++ /dev/null @@ -1,33 +0,0 @@ -module Hsbot.Irc.Plugin.Ping - ( ircBotPluginPing - ) where - -import Control.Concurrent.Chan -import Control.Exception -import Control.Monad.State -import Prelude hiding (catch) - -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Utils - --- | The plugin's main entry point -ircBotPluginPing :: Chan IrcBotMsg -> Chan IrcBotMsg -> IO () -ircBotPluginPing myChan masterChan = do - let plugin = IrcPluginState { ircPluginName = "Ping" - , ircPluginChan = myChan - , ircPluginMasterChan = masterChan } - _ <- (execStateT run plugin) `catch` (\(_ :: AsyncException) -> return plugin) - return () - --- | The IrcPlugin monad main function -run :: IrcPlugin () -run = forever $ do - msg <- readMsg - eval msg - where - eval :: IrcBotMsg -> IrcPlugin () - eval (InIrcMsg msg) - | (ircMsgCommand msg) == "PING" = writeMsg . OutIrcMsg $ IrcMsg Nothing "PONG" (ircMsgParameters msg) - | otherwise = return () - eval _ = return () - diff --git a/Hsbot/Irc/Plugin/Quote.hs b/Hsbot/Irc/Plugin/Quote.hs deleted file mode 100644 index 0335d8b..0000000 --- a/Hsbot/Irc/Plugin/Quote.hs +++ /dev/null @@ -1,174 +0,0 @@ -module Hsbot.Irc.Plugin.Quote - ( ircBotPluginQuote - ) where - -import Control.Concurrent.Chan -import Control.Exception -import Control.Monad.State -import qualified Data.Map as M -import Data.Maybe(fromMaybe) -import qualified Data.Text as T -import qualified Data.Text.IO as TIO -import Data.Time -import System.Directory -import IO hiding (catch) -import Prelude hiding (catch) -import System.FilePath -import System.Posix.Files -import System.Random(randomRIO) - -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Utils - --- | A quote element -data QuoteElt = QuoteElt - { eltQuoter :: String - , eltQuote :: String - } deriving (Read, Show) - --- | A quote object -data Quote = Quote - { quoter :: String - , quote :: [QuoteElt] - , quoteTime :: UTCTime - , votes :: Int - } deriving (Read, Show) - --- | A QuoteBot state -data QuoteBotState = QuoteBotState - { nextQuoteId :: Integer - , quoteBotDB :: M.Map Integer Quote - , quotesInProgress :: M.Map Integer Quote - } deriving (Read, Show) - --- | The QuoteBot monad -type QuoteBot a = StateT QuoteBotState (StateT IrcPluginState IO) a - --- | The plugin's main entry point -ircBotPluginQuote :: Chan IrcBotMsg -> Chan IrcBotMsg -> IO () -ircBotPluginQuote myChan masterChan = do - -- First of all we restore the database - dir <- getAppUserDataDirectory "hsbot" - let dbfile = dir "quotedb.txt" - dbfileExists <- fileExist dbfile - if not dbfileExists - then - let quoteBot = QuoteBotState 0 M.empty M.empty - in TIO.writeFile dbfile (T.pack $ show quoteBot) - else - return () - txtQuoteBot <- TIO.readFile $ dbfile - let quoteBot = read (T.unpack txtQuoteBot) :: QuoteBotState - -- The plugin main loop - let plugin = IrcPluginState { ircPluginName = "Quote" - , ircPluginChan = myChan - , ircPluginMasterChan = masterChan } - evalStateT (mapM_ sendRegisterCommand ["quote"]) plugin - _ <- (evalStateT (run quoteBot) plugin) `catch` (\(_ :: AsyncException) -> return quoteBot) - evalStateT (mapM_ sendUnregisterCommand ["quote"]) plugin - --- | The IrcPlugin monad main function -run :: QuoteBotState -> IrcPlugin (QuoteBotState) -run quoteBot = do - msg <- readMsg - quoteBot' <- eval msg - run quoteBot' - where - -- | evaluate what we just received - eval :: IrcBotMsg -> IrcPlugin (QuoteBotState) - eval (IntIrcCmd intCmd) - | ircCmdCmd intCmd == "RUN" = do - quoteBot' <- execStateT (runCommand intCmd) quoteBot - return quoteBot' - | otherwise = return quoteBot - eval (InIrcMsg _) = return (quoteBot) - eval (OutIrcMsg _) = return (quoteBot) - --- | run a command we received -runCommand :: IrcCmd -> QuoteBot () -runCommand intCmd - | theCommand == "quote" = runQuoteCommand - | otherwise = return () - where - -- | the message is a quote command - runQuoteCommand :: QuoteBot () - | length args == 0 = do - quoteDB <- gets quoteBotDB - x <- liftIO $ randomRIO (0, (length $ M.keys quoteDB) - 1) - if (length $ M.keys quoteDB) > 0 - then - mapM_ (lift . answerMsg request) (formatQuote (M.keys quoteDB !! x) (M.elems quoteDB !! x)) - else - lift $ answerMsg request "The quote database is empty." - | otherwise = do - dispatchQuoteCmd $ head args - -- | quote command dispatcher - dispatchQuoteCmd :: String -> QuoteBot () - dispatchQuoteCmd cmd - | cmd == "start" = do - quoteBot <- get - now <- liftIO $ getCurrentTime - let sender = takeWhile (/= '!') $ fromMaybe "ARGH" (ircMsgPrefix request) - newQuote = Quote sender [(quoteElt stuff)] now 0 - quoteId = nextQuoteId quoteBot - quotesInProgress' = M.insert quoteId newQuote (quotesInProgress quoteBot) - put $ quoteBot { nextQuoteId = quoteId + 1, quotesInProgress = quotesInProgress' } - lift $ answerMsg request ("New quoteId : " ++ show quoteId) - syncQuoteBot - | cmd == "append" = do - quoteBot <- get - case reads (head stuff) of - [(quoteId :: Integer,"")] -> do - case M.lookup quoteId (quotesInProgress quoteBot) of - Just theQuote -> do - let newQuote = theQuote { quote = (quoteElt $ tail stuff) : (quote theQuote) } - quotesInProgress' = M.insert quoteId newQuote (quotesInProgress quoteBot) - put $ quoteBot { quotesInProgress = quotesInProgress' } - syncQuoteBot - Nothing -> lift $ answerMsg request ("quoteId not found : " ++ (show quoteId)) - _ -> lift $ answerMsg request ("Invalid quoteId : " ++ (head stuff)) - | cmd == "commit" = do - quoteBot <- get - case reads (head stuff) of - [(quoteId :: Integer,"")] -> do - case M.lookup quoteId (quotesInProgress quoteBot) of - Just theQuote -> do - let quoteBotDB' = M.insert quoteId theQuote (quoteBotDB quoteBot) - quotesInProgress' = M.delete quoteId (quotesInProgress quoteBot) - put $ quoteBot { quoteBotDB = quoteBotDB', quotesInProgress = quotesInProgress' } - syncQuoteBot - Nothing -> lift $ answerMsg request ("quoteId not found : " ++ (show quoteId)) - _ -> lift $ answerMsg request ("Invalid quoteId : " ++ (head stuff)) - -- | cmd == "abort" = - | otherwise = lift $ answerMsg request ("Invalid command : " ++ cmd) - -- | Gets the new QuoteElt - quoteElt :: [String] -> QuoteElt - quoteElt msg = do - let budy = head $ msg - theQuote = unwords . tail $ msg - QuoteElt budy theQuote - -- | utilities - params = words . ircCmdMsg $ intCmd - theCommand = head params - args = tail params - stuff = tail args - request = ircCmdBotMsg intCmd - --- | The function that sync the quoteDB on disk -syncQuoteBot :: QuoteBot () -syncQuoteBot = do - dir <- liftIO $ getAppUserDataDirectory "hsbot" - let dbfile = dir "quotedb.txt" - file' <- liftIO $ openFile dbfile WriteMode - quoteBot <- get - liftIO . hPutStr file' $ show quoteBot - liftIO $ hClose file' - -formatQuote :: Integer -> Quote -> [String] -formatQuote quoteId theQuote = - ("+---| " ++ (show quoteId) ++ " |-- Reported by " ++ (quoter theQuote) ++ " on " ++ (show $ quoteTime theQuote)) : - foldl (\acc x -> formatQuoteElt x : acc) ["`------------------------------------------"] (quote theQuote) - where - formatQuoteElt :: QuoteElt -> String - formatQuoteElt quoteElt = "| <" ++ (eltQuoter quoteElt) ++ "> " ++ (eltQuote quoteElt) - diff --git a/Hsbot/Irc/Plugin/Utils.hs b/Hsbot/Irc/Plugin/Utils.hs deleted file mode 100644 index 1e54d3a..0000000 --- a/Hsbot/Irc/Plugin/Utils.hs +++ /dev/null @@ -1,66 +0,0 @@ -module Hsbot.Irc.Plugin.Utils - ( IrcPlugin - , IrcPluginState (..) - , answerMsg - , readMsg - , sendCommand - , sendCommandWithRequest - , sendRegisterCommand - , sendUnregisterCommand - , writeMsg - ) where - -import Control.Concurrent -import Control.Concurrent.Chan () -import Control.Monad.State -import Data.Maybe (fromMaybe) - -import Hsbot.Irc.Message - --- | The IrcPlugin monad -type IrcPlugin = StateT IrcPluginState IO - --- | A plugin state -data IrcPluginState = IrcPluginState - { ircPluginName :: String -- The plugin's name - , ircPluginChan :: Chan IrcBotMsg -- The plugin chan - , ircPluginMasterChan :: Chan IrcBotMsg -- The master's chan - } - ---- | Basic input output for IrcPlugins -readMsg :: IrcPlugin (IrcBotMsg) -readMsg = do - chan <- gets ircPluginChan - input <- liftIO $ readChan chan - return input - -writeMsg :: IrcBotMsg -> IrcPlugin () -writeMsg (OutIrcMsg msg) = do - chan <- gets ircPluginMasterChan - liftIO $ writeChan chan (OutIrcMsg msg) -writeMsg _ = return () - -answerMsg :: IrcMsg -> String -> IrcPlugin () -answerMsg request msg = do - let chanOrigin = head $ ircMsgParameters request - sender = takeWhile (/= '!') $ fromMaybe "" (ircMsgPrefix request) - case head chanOrigin of - '#' -> writeMsg . OutIrcMsg $ IrcMsg Nothing "PRIVMSG" [chanOrigin, msg] - _ -> writeMsg . OutIrcMsg $ IrcMsg Nothing "PRIVMSG" [sender, msg] - --- | Command management -sendCommand :: String -> String -> String -> IrcPlugin () -sendCommand cmd to params = sendCommandWithRequest cmd to params emptyIrcMsg - -sendCommandWithRequest :: String -> String -> String -> IrcMsg -> IrcPlugin () -sendCommandWithRequest cmd to params originalRequest = do - masterChan <- gets ircPluginMasterChan - from <- gets ircPluginName - liftIO . writeChan masterChan . IntIrcCmd $ IrcCmd cmd from to params originalRequest - -sendRegisterCommand :: String -> IrcPlugin () -sendRegisterCommand cmd = sendCommand "REGISTER" "CORE" cmd - -sendUnregisterCommand :: String -> IrcPlugin () -sendUnregisterCommand cmd = sendCommand "UNREGISTER" "CORE" cmd - diff --git a/Hsbot/Irc/Server.hs b/Hsbot/Irc/Server.hs deleted file mode 100644 index 3c20e6d..0000000 --- a/Hsbot/Irc/Server.hs +++ /dev/null @@ -1,35 +0,0 @@ -module Hsbot.Irc.Server - ( initServerConnection - , sendIrcMsg - ) where - -import Control.Concurrent.Chan -import Control.Monad.State - -import Hsbot.Irc.Config -import Hsbot.Irc.Message -import Hsbot.Irc.Types - --- | Setup a newly connected server by sending nick and join stuff -initServerConnection :: IrcConfig -> IrcServer () -initServerConnection config = do - sendIrcMsg $ IrcMsg Nothing "NICK" [(ircConfigNickname config)] - sendIrcMsg $ IrcMsg Nothing "USER" [(ircConfigNickname config), "0", "*", (ircConfigRealname config)] - when (not . null $ ircConfigPassword config) $ do - sendIrcMsg $ IrcMsg Nothing "PRIVMSG" ["nickserv", "identify", (ircConfigPassword config)] - mapM_ joinChan (ircConfigChannels config) - --- | Joins a chan -joinChan :: String -> IrcServer () -joinChan channel = do - ircServer <- get - let oldChannels = ircServerChannels ircServer - sendIrcMsg $ IrcMsg Nothing "JOIN" [channel] - put $ ircServer { ircServerChannels = channel : oldChannels } - --- | Sends an IrcMsg -sendIrcMsg :: IrcMsg -> IrcServer () -sendIrcMsg ircMsg = do - chan <- gets ircServerChan - liftIO $ writeChan chan (OutIrcMsg ircMsg) - diff --git a/Hsbot/Irc/Types.hs b/Hsbot/Irc/Types.hs deleted file mode 100644 index 63411df..0000000 --- a/Hsbot/Irc/Types.hs +++ /dev/null @@ -1,48 +0,0 @@ -module Hsbot.Irc.Types - ( IrcBot - , IrcBotState (..) - , IrcServer - , IrcServerState (..) - , first - ) where - -import Control.Concurrent -import Control.Monad.State -import qualified Data.Map as M -import System.IO - -import Hsbot.Irc.Config -import Hsbot.Irc.Message -import Hsbot.Irc.Plugin.Utils -import Hsbot.Types - --- | The Ircbot monad -type IrcBot = StateT IrcBotState IO - --- | An Ircbot state -data IrcBotState = IrcBotState - { ircBotPlugins :: M.Map String (IrcPluginState, MVar (), ThreadId) -- Loaded plugins - , ircBotCommands :: M.Map String [String] -- Loaded plugins - , ircBotChan :: Chan IrcBotMsg -- The IrcBot's communication channel - , ircBotMasterChan :: Chan BotMsg -- The Hsbot communication channel - , ircBotServerState :: IrcServerState -- The state of the IrcServer - , ircBotHandle :: Handle -- The server's socket/handle - , ircBotConfig :: IrcConfig -- The starting configuration - , ircBotResumeData :: ResumeData -- the necessary data to resume the bot's operations on reboot - } - --- | The IrcServer monad -type IrcServer = StateT IrcServerState IrcBot - --- | An IRC server -data IrcServerState = IrcServerState - { ircServerId :: String -- the server's address - , ircServerChannels :: [String] -- the Channels we are connected to - , ircServerNickname :: String -- the hsbot's nickname - , ircServerCommandPrefix :: Char -- the prefix the ircbot will recognize as commands - , ircServerChan :: Chan IrcBotMsg -- the IrcBot channel - } - --- | Utilities for triplets -first :: (a, b, c) -> a -first (a, _, _) = a diff --git a/Hsbot/Irc/doc/rfc2812.txt b/Hsbot/Irc/doc/rfc2812.txt deleted file mode 100644 index bfa2711..0000000 --- a/Hsbot/Irc/doc/rfc2812.txt +++ /dev/null @@ -1,3531 +0,0 @@ - - - - - - -Network Working Group C. Kalt -Request for Comments: 2812 April 2000 -Updates: 1459 -Category: Informational - - - Internet Relay Chat: Client Protocol - -Status of this Memo - - This memo provides information for the Internet community. It does - not specify an Internet standard of any kind. Distribution of this - memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (2000). All Rights Reserved. - -IESG NOTE: - - The IRC protocol itself enables several possibilities of transferring - data between clients, and just like with other transfer mechanisms - like email, the receiver of the data has to be careful about how the - data is handled. For more information on security issues with the IRC - protocol, see for example http://www.irchelp.org/irchelp/security/. - -Abstract - - The IRC (Internet Relay Chat) protocol is for use with text based - conferencing; the simplest client being any socket program capable of - connecting to the server. - - This document defines the Client Protocol, and assumes that the - reader is familiar with the IRC Architecture [IRC-ARCH]. - -Table of Contents - - 1. Labels ..................................................... 3 - 1.1 Servers ................................................ 3 - 1.2 Clients ................................................ 3 - 1.2.1 Users ............................................. 4 - 1.2.1.1 Operators .................................... 4 - 1.2.2 Services .......................................... 4 - 1.3 Channels ............................................... 4 - 2. The IRC Client Specification ............................... 5 - 2.1 Overview ............................................... 5 - 2.2 Character codes ........................................ 5 - 2.3 Messages ............................................... 5 - - - -Kalt Informational [Page 1] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 2.3.1 Message format in Augmented BNF ................... 6 - 2.4 Numeric replies ........................................ 8 - 2.5 Wildcard expressions ................................... 9 - 3. Message Details ............................................ 9 - 3.1 Connection Registration ................................ 10 - 3.1.1 Password message .................................. 10 - 3.1.2 Nick message ...................................... 10 - 3.1.3 User message ...................................... 11 - 3.1.4 Oper message ...................................... 12 - 3.1.5 User mode message ................................. 12 - 3.1.6 Service message ................................... 13 - 3.1.7 Quit .............................................. 14 - 3.1.8 Squit ............................................. 15 - 3.2 Channel operations ..................................... 15 - 3.2.1 Join message ...................................... 16 - 3.2.2 Part message ...................................... 17 - 3.2.3 Channel mode message .............................. 18 - 3.2.4 Topic message ..................................... 19 - 3.2.5 Names message ..................................... 20 - 3.2.6 List message ...................................... 21 - 3.2.7 Invite message .................................... 21 - 3.2.8 Kick command ...................................... 22 - 3.3 Sending messages ....................................... 23 - 3.3.1 Private messages .................................. 23 - 3.3.2 Notice ............................................ 24 - 3.4 Server queries and commands ............................ 25 - 3.4.1 Motd message ...................................... 25 - 3.4.2 Lusers message .................................... 25 - 3.4.3 Version message ................................... 26 - 3.4.4 Stats message ..................................... 26 - 3.4.5 Links message ..................................... 27 - 3.4.6 Time message ...................................... 28 - 3.4.7 Connect message ................................... 28 - 3.4.8 Trace message ..................................... 29 - 3.4.9 Admin command ..................................... 30 - 3.4.10 Info command ...................................... 31 - 3.5 Service Query and Commands ............................. 31 - 3.5.1 Servlist message .................................. 31 - 3.5.2 Squery ............................................ 32 - 3.6 User based queries ..................................... 32 - 3.6.1 Who query ......................................... 32 - 3.6.2 Whois query ....................................... 33 - 3.6.3 Whowas ............................................ 34 - 3.7 Miscellaneous messages ................................. 34 - 3.7.1 Kill message ...................................... 35 - 3.7.2 Ping message ...................................... 36 - 3.7.3 Pong message ...................................... 37 - 3.7.4 Error ............................................. 37 - - - -Kalt Informational [Page 2] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 4. Optional features .......................................... 38 - 4.1 Away ................................................... 38 - 4.2 Rehash message ......................................... 39 - 4.3 Die message ............................................ 39 - 4.4 Restart message ........................................ 40 - 4.5 Summon message ......................................... 40 - 4.6 Users .................................................. 41 - 4.7 Operwall message ....................................... 41 - 4.8 Userhost message ....................................... 42 - 4.9 Ison message ........................................... 42 - 5. Replies .................................................... 43 - 5.1 Command responses ...................................... 43 - 5.2 Error Replies .......................................... 53 - 5.3 Reserved numerics ...................................... 59 - 6. Current implementations .................................... 60 - 7. Current problems ........................................... 60 - 7.1 Nicknames .............................................. 60 - 7.2 Limitation of wildcards ................................ 61 - 7.3 Security considerations ................................ 61 - 8. Current support and availability ........................... 61 - 9. Acknowledgements ........................................... 61 - 10. References ................................................ 62 - 11. Author's Address .......................................... 62 - 12. Full Copyright Statement .................................. 63 - -1. Labels - - This section defines the identifiers used for the various components - of the IRC protocol. - -1.1 Servers - - Servers are uniquely identified by their name, which has a maximum - length of sixty three (63) characters. See the protocol grammar - rules (section 2.3.1) for what may and may not be used in a server - name. - -1.2 Clients - - For each client all servers MUST have the following information: a - netwide unique identifier (whose format depends on the type of - client) and the server which introduced the client. - - - - - - - - - -Kalt Informational [Page 3] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -1.2.1 Users - - Each user is distinguished from other users by a unique nickname - having a maximum length of nine (9) characters. See the protocol - grammar rules (section 2.3.1) for what may and may not be used in a - nickname. - - While the maximum length is limited to nine characters, clients - SHOULD accept longer strings as they may become used in future - evolutions of the protocol. - -1.2.1.1 Operators - - To allow a reasonable amount of order to be kept within the IRC - network, a special class of users (operators) is allowed to perform - general maintenance functions on the network. Although the powers - granted to an operator can be considered as 'dangerous', they are - nonetheless often necessary. Operators SHOULD be able to perform - basic network tasks such as disconnecting and reconnecting servers as - needed. In recognition of this need, the protocol discussed herein - provides for operators only to be able to perform such functions. - See sections 3.1.8 (SQUIT) and 3.4.7 (CONNECT). - - A more controversial power of operators is the ability to remove a - user from the connected network by 'force', i.e., operators are able - to close the connection between any client and server. The - justification for this is very delicate since its abuse is both - destructive and annoying, and its benefits close to inexistent. For - further details on this type of action, see section 3.7.1 (KILL). - -1.2.2 Services - - Each service is distinguished from other services by a service name - composed of a nickname and a server name. As for users, the nickname - has a maximum length of nine (9) characters. See the protocol - grammar rules (section 2.3.1) for what may and may not be used in a - nickname. - -1.3 Channels - - Channels names are strings (beginning with a '&', '#', '+' or '!' - character) of length up to fifty (50) characters. Apart from the - requirement that the first character is either '&', '#', '+' or '!', - the only restriction on a channel name is that it SHALL NOT contain - any spaces (' '), a control G (^G or ASCII 7), a comma (','). Space - is used as parameter separator and command is used as a list item - separator by the protocol). A colon (':') can also be used as a - delimiter for the channel mask. Channel names are case insensitive. - - - -Kalt Informational [Page 4] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - See the protocol grammar rules (section 2.3.1) for the exact syntax - of a channel name. - - Each prefix characterizes a different channel type. The definition - of the channel types is not relevant to the client-server protocol - and thus it is beyond the scope of this document. More details can - be found in "Internet Relay Chat: Channel Management" [IRC-CHAN]. - -2. The IRC Client Specification - -2.1 Overview - - The protocol as described herein is for use only with client to - server connections when the client registers as a user. - -2.2 Character codes - - No specific character set is specified. The protocol is based on a - set of codes which are composed of eight (8) bits, making up an - octet. Each message may be composed of any number of these octets; - however, some octet values are used for control codes, which act as - message delimiters. - - Regardless of being an 8-bit protocol, the delimiters and keywords - are such that protocol is mostly usable from US-ASCII terminal and a - telnet connection. - - Because of IRC's Scandinavian origin, the characters {}|^ are - considered to be the lower case equivalents of the characters []\~, - respectively. This is a critical issue when determining the - equivalence of two nicknames or channel names. - -2.3 Messages - - Servers and clients send each other messages, which may or may not - generate a reply. If the message contains a valid command, as - described in later sections, the client should expect a reply as - specified but it is not advised to wait forever for the reply; client - to server and server to server communication is essentially - asynchronous by nature. - - Each IRC message may consist of up to three main parts: the prefix - (OPTIONAL), the command, and the command parameters (maximum of - fifteen (15)). The prefix, command, and all parameters are separated - by one ASCII space character (0x20) each. - - - - - - -Kalt Informational [Page 5] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - The presence of a prefix is indicated with a single leading ASCII - colon character (':', 0x3b), which MUST be the first character of the - message itself. There MUST be NO gap (whitespace) between the colon - and the prefix. The prefix is used by servers to indicate the true - origin of the message. If the prefix is missing from the message, it - is assumed to have originated from the connection from which it was - received from. Clients SHOULD NOT use a prefix when sending a - message; if they use one, the only valid prefix is the registered - nickname associated with the client. - - The command MUST either be a valid IRC command or a three (3) digit - number represented in ASCII text. - - IRC messages are always lines of characters terminated with a CR-LF - (Carriage Return - Line Feed) pair, and these messages SHALL NOT - exceed 512 characters in length, counting all characters including - the trailing CR-LF. Thus, there are 510 characters maximum allowed - for the command and its parameters. There is no provision for - continuation of message lines. See section 6 for more details about - current implementations. - -2.3.1 Message format in Augmented BNF - - The protocol messages must be extracted from the contiguous stream of - octets. The current solution is to designate two characters, CR and - LF, as message separators. Empty messages are silently ignored, - which permits use of the sequence CR-LF between messages without - extra problems. - - The extracted message is parsed into the components , - and list of parameters (). - - The Augmented BNF representation for this is: - - message = [ ":" prefix SPACE ] command [ params ] crlf - prefix = servername / ( nickname [ [ "!" user ] "@" host ] ) - command = 1*letter / 3digit - params = *14( SPACE middle ) [ SPACE ":" trailing ] - =/ 14( SPACE middle ) [ SPACE [ ":" ] trailing ] - - nospcrlfcl = %x01-09 / %x0B-0C / %x0E-1F / %x21-39 / %x3B-FF - ; any octet except NUL, CR, LF, " " and ":" - middle = nospcrlfcl *( ":" / nospcrlfcl ) - trailing = *( ":" / " " / nospcrlfcl ) - - SPACE = %x20 ; space character - crlf = %x0D %x0A ; "carriage return" "linefeed" - - - - -Kalt Informational [Page 6] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - NOTES: - 1) After extracting the parameter list, all parameters are equal - whether matched by or . is just a - syntactic trick to allow SPACE within the parameter. - - 2) The NUL (%x00) character is not special in message framing, and - basically could end up inside a parameter, but it would cause - extra complexities in normal C string handling. Therefore, NUL - is not allowed within messages. - - Most protocol messages specify additional semantics and syntax for - the extracted parameter strings dictated by their position in the - list. For example, many server commands will assume that the first - parameter after the command is the list of targets, which can be - described with: - - target = nickname / server - msgtarget = msgto *( "," msgto ) - msgto = channel / ( user [ "%" host ] "@" servername ) - msgto =/ ( user "%" host ) / targetmask - msgto =/ nickname / ( nickname "!" user "@" host ) - channel = ( "#" / "+" / ( "!" channelid ) / "&" ) chanstring - [ ":" chanstring ] - servername = hostname - host = hostname / hostaddr - hostname = shortname *( "." shortname ) - shortname = ( letter / digit ) *( letter / digit / "-" ) - *( letter / digit ) - ; as specified in RFC 1123 [HNAME] - hostaddr = ip4addr / ip6addr - ip4addr = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit - ip6addr = 1*hexdigit 7( ":" 1*hexdigit ) - ip6addr =/ "0:0:0:0:0:" ( "0" / "FFFF" ) ":" ip4addr - nickname = ( letter / special ) *8( letter / digit / special / "-" ) - targetmask = ( "$" / "#" ) mask - ; see details on allowed masks in section 3.3.1 - chanstring = %x01-07 / %x08-09 / %x0B-0C / %x0E-1F / %x21-2B - chanstring =/ %x2D-39 / %x3B-FF - ; any octet except NUL, BELL, CR, LF, " ", "," and ":" - channelid = 5( %x41-5A / digit ) ; 5( A-Z / 0-9 ) - - - - - - - - - - - -Kalt Informational [Page 7] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Other parameter syntaxes are: - - user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF ) - ; any octet except NUL, CR, LF, " " and "@" - key = 1*23( %x01-05 / %x07-08 / %x0C / %x0E-1F / %x21-7F ) - ; any 7-bit US_ASCII character, - ; except NUL, CR, LF, FF, h/v TABs, and " " - letter = %x41-5A / %x61-7A ; A-Z / a-z - digit = %x30-39 ; 0-9 - hexdigit = digit / "A" / "B" / "C" / "D" / "E" / "F" - special = %x5B-60 / %x7B-7D - ; "[", "]", "\", "`", "_", "^", "{", "|", "}" - - NOTES: - 1) The syntax is given here for the sole purpose of - indicating the format to follow for IP addresses. This - reflects the fact that the only available implementations of - this protocol uses TCP/IP as underlying network protocol but is - not meant to prevent other protocols to be used. - - 2) has a maximum length of 63 characters. This is a - limitation of the protocol as internet hostnames (in - particular) can be longer. Such restriction is necessary - because IRC messages are limited to 512 characters in length. - Clients connecting from a host which name is longer than 63 - characters are registered using the host (numeric) address - instead of the host name. - - 3) Some parameters used in the following sections of this - documents are not defined here as there is nothing specific - about them besides the name that is used for convenience. - These parameters follow the general syntax defined for - . - -2.4 Numeric replies - - Most of the messages sent to the server generate a reply of some - sort. The most common reply is the numeric reply, used for both - errors and normal replies. The numeric reply MUST be sent as one - message consisting of the sender prefix, the three-digit numeric, and - the target of the reply. A numeric reply is not allowed to originate - from a client. In all other respects, a numeric reply is just like a - normal message, except that the keyword is made up of 3 numeric - digits rather than a string of letters. A list of different replies - is supplied in section 5 (Replies). - - - - - - -Kalt Informational [Page 8] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -2.5 Wildcard expressions - - When wildcards are allowed in a string, it is referred as a "mask". - - For string matching purposes, the protocol allows the use of two - special characters: '?' (%x3F) to match one and only one character, - and '*' (%x2A) to match any number of any characters. These two - characters can be escaped using the character '\' (%x5C). - - The Augmented BNF syntax for this is: - - mask = *( nowild / noesc wildone / noesc wildmany ) - wildone = %x3F - wildmany = %x2A - nowild = %x01-29 / %x2B-3E / %x40-FF - ; any octet except NUL, "*", "?" - noesc = %x01-5B / %x5D-FF - ; any octet except NUL and "\" - matchone = %x01-FF - ; matches wildone - matchmany = *matchone - ; matches wildmany - - Examples: - - a?c ; Matches any string of 3 characters in length starting - with "a" and ending with "c" - - a*c ; Matches any string of at least 2 characters in length - starting with "a" and ending with "c" - -3. Message Details - - On the following pages there are descriptions of each message - recognized by the IRC server and client. All commands described in - this section MUST be implemented by any server for this protocol. - - Where the reply ERR_NOSUCHSERVER is returned, it means that the - target of the message could not be found. The server MUST NOT send - any other replies after this error for that command. - - The server to which a client is connected is required to parse the - complete message, and return any appropriate errors. - - If multiple parameters is presented, then each MUST be checked for - validity and appropriate responses MUST be sent back to the client. - In the case of incorrect messages which use parameter lists with - comma as an item separator, a reply MUST be sent for each item. - - - -Kalt Informational [Page 9] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.1 Connection Registration - - The commands described here are used to register a connection with an - IRC server as a user as well as to correctly disconnect. - - A "PASS" command is not required for a client connection to be - registered, but it MUST precede the latter of the NICK/USER - combination (for a user connection) or the SERVICE command (for a - service connection). The RECOMMENDED order for a client to register - is as follows: - - 1. Pass message - 2. Nick message 2. Service message - 3. User message - - Upon success, the client will receive an RPL_WELCOME (for users) or - RPL_YOURESERVICE (for services) message indicating that the - connection is now registered and known the to the entire IRC network. - The reply message MUST contain the full client identifier upon which - it was registered. - -3.1.1 Password message - - Command: PASS - Parameters: - - The PASS command is used to set a 'connection password'. The - optional password can and MUST be set before any attempt to register - the connection is made. Currently this requires that user send a - PASS command before sending the NICK/USER combination. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED - - Example: - - PASS secretpasswordhere - -3.1.2 Nick message - - - Command: NICK - Parameters: - - NICK command is used to give user a nickname or change the existing - one. - - - - -Kalt Informational [Page 10] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Numeric Replies: - - ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME - ERR_NICKNAMEINUSE ERR_NICKCOLLISION - ERR_UNAVAILRESOURCE ERR_RESTRICTED - - Examples: - - NICK Wiz ; Introducing new nick "Wiz" if session is - still unregistered, or user changing his - nickname to "Wiz" - - :WiZ!jto@tolsun.oulu.fi NICK Kilroy - ; Server telling that WiZ changed his - nickname to Kilroy. - -3.1.3 User message - - Command: USER - Parameters: - - The USER command is used at the beginning of connection to specify - the username, hostname and realname of a new user. - - The parameter should be a numeric, and can be used to - automatically set user modes when registering with the server. This - parameter is a bitmask, with only 2 bits having any signification: if - the bit 2 is set, the user mode 'w' will be set and if the bit 3 is - set, the user mode 'i' will be set. (See Section 3.1.5 "User - Modes"). - - The may contain space characters. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED - - Example: - - USER guest 0 * :Ronnie Reagan ; User registering themselves with a - username of "guest" and real name - "Ronnie Reagan". - - USER guest 8 * :Ronnie Reagan ; User registering themselves with a - username of "guest" and real name - "Ronnie Reagan", and asking to be set - invisible. - - - - -Kalt Informational [Page 11] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.1.4 Oper message - - Command: OPER - Parameters: - - A normal user uses the OPER command to obtain operator privileges. - The combination of and are REQUIRED to gain - Operator privileges. Upon success, the user will receive a MODE - message (see section 3.1.5) indicating the new user modes. - - Numeric Replies: - - ERR_NEEDMOREPARAMS RPL_YOUREOPER - ERR_NOOPERHOST ERR_PASSWDMISMATCH - - Example: - - OPER foo bar ; Attempt to register as an operator - using a username of "foo" and "bar" - as the password. - -3.1.5 User mode message - - Command: MODE - Parameters: - *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) ) - - The user MODE's are typically changes which affect either how the - client is seen by others or what 'extra' messages the client is sent. - - A user MODE command MUST only be accepted if both the sender of the - message and the nickname given as a parameter are both the same. If - no other parameter is given, then the server will return the current - settings for the nick. - - The available modes are as follows: - - a - user is flagged as away; - i - marks a users as invisible; - w - user receives wallops; - r - restricted user connection; - o - operator flag; - O - local operator flag; - s - marks a user for receipt of server notices. - - Additional modes may be available later on. - - - - - -Kalt Informational [Page 12] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - The flag 'a' SHALL NOT be toggled by the user using the MODE command, - instead use of the AWAY command is REQUIRED. - - If a user attempts to make themselves an operator using the "+o" or - "+O" flag, the attempt SHOULD be ignored as users could bypass the - authentication mechanisms of the OPER command. There is no - restriction, however, on anyone `deopping' themselves (using "-o" or - "-O"). - - On the other hand, if a user attempts to make themselves unrestricted - using the "-r" flag, the attempt SHOULD be ignored. There is no - restriction, however, on anyone `deopping' themselves (using "+r"). - This flag is typically set by the server upon connection for - administrative reasons. While the restrictions imposed are left up - to the implementation, it is typical that a restricted user not be - allowed to change nicknames, nor make use of the channel operator - status on channels. - - The flag 's' is obsolete but MAY still be used. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_USERSDONTMATCH - ERR_UMODEUNKNOWNFLAG RPL_UMODEIS - - Examples: - - MODE WiZ -w ; Command by WiZ to turn off - reception of WALLOPS messages. - - MODE Angel +i ; Command from Angel to make herself - invisible. - - MODE WiZ -o ; WiZ 'deopping' (removing operator - status). - -3.1.6 Service message - - Command: SERVICE - Parameters: - - - The SERVICE command to register a new service. Command parameters - specify the service nickname, distribution, type and info of a new - service. - - - - - - -Kalt Informational [Page 13] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - The parameter is used to specify the visibility of a - service. The service may only be known to servers which have a name - matching the distribution. For a matching server to have knowledge - of the service, the network path between that server and the server - on which the service is connected MUST be composed of servers which - names all match the mask. - - The parameter is currently reserved for future usage. - - Numeric Replies: - - ERR_ALREADYREGISTRED ERR_NEEDMOREPARAMS - ERR_ERRONEUSNICKNAME - RPL_YOURESERVICE RPL_YOURHOST - RPL_MYINFO - - Example: - - SERVICE dict * *.fr 0 0 :French Dictionary ; Service registering - itself with a name of "dict". This - service will only be available on - servers which name matches "*.fr". - -3.1.7 Quit - - Command: QUIT - Parameters: [ ] - - A client session is terminated with a quit message. The server - acknowledges this by sending an ERROR message to the client. - - Numeric Replies: - - None. - - Example: - - QUIT :Gone to have lunch ; Preferred message format. - - :syrk!kalt@millennium.stealth.net QUIT :Gone to have lunch ; User - syrk has quit IRC to have lunch. - - - - - - - - - - -Kalt Informational [Page 14] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.1.8 Squit - - Command: SQUIT - Parameters: - - The SQUIT command is available only to operators. It is used to - disconnect server links. Also servers can generate SQUIT messages on - error conditions. A SQUIT message may also target a remote server - connection. In this case, the SQUIT message will simply be sent to - the remote server without affecting the servers in between the - operator and the remote server. - - The SHOULD be supplied by all operators who execute a SQUIT - for a remote server. The server ordered to disconnect its peer - generates a WALLOPS message with included, so that other - users may be aware of the reason of this action. - - Numeric replies: - - ERR_NOPRIVILEGES ERR_NOSUCHSERVER - ERR_NEEDMOREPARAMS - - Examples: - - SQUIT tolsun.oulu.fi :Bad Link ? ; Command to uplink of the server - tolson.oulu.fi to terminate its - connection with comment "Bad Link". - - :Trillian SQUIT cm22.eng.umd.edu :Server out of control ; Command - from Trillian from to disconnect - "cm22.eng.umd.edu" from the net with - comment "Server out of control". - -3.2 Channel operations - - This group of messages is concerned with manipulating channels, their - properties (channel modes), and their contents (typically users). - For this reason, these messages SHALL NOT be made available to - services. - - All of these messages are requests which will or will not be granted - by the server. The server MUST send a reply informing the user - whether the request was granted, denied or generated an error. When - the server grants the request, the message is typically sent back - (eventually reformatted) to the user with the prefix set to the user - itself. - - - - - -Kalt Informational [Page 15] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - The rules governing how channels are managed are enforced by the - servers. These rules are beyond the scope of this document. More - details are found in "Internet Relay Chat: Channel Management" [IRC- - CHAN]. - -3.2.1 Join message - - Command: JOIN - Parameters: ( *( "," ) [ *( "," ) ] ) - / "0" - - The JOIN command is used by a user to request to start listening to - the specific channel. Servers MUST be able to parse arguments in the - form of a list of target, but SHOULD NOT use lists when sending JOIN - messages to clients. - - Once a user has joined a channel, he receives information about - all commands his server receives affecting the channel. This - includes JOIN, MODE, KICK, PART, QUIT and of course PRIVMSG/NOTICE. - This allows channel members to keep track of the other channel - members, as well as channel modes. - - If a JOIN is successful, the user receives a JOIN message as - confirmation and is then sent the channel's topic (using RPL_TOPIC) and - the list of users who are on the channel (using RPL_NAMREPLY), which - MUST include the user joining. - - Note that this message accepts a special argument ("0"), which is - a special request to leave all channels the user is currently a member - of. The server will process this message as if the user had sent - a PART command (See Section 3.2.2) for each channel he is a member - of. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN - ERR_INVITEONLYCHAN ERR_BADCHANNELKEY - ERR_CHANNELISFULL ERR_BADCHANMASK - ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS - ERR_TOOMANYTARGETS ERR_UNAVAILRESOURCE - RPL_TOPIC - - Examples: - - JOIN #foobar ; Command to join channel #foobar. - - JOIN &foo fubar ; Command to join channel &foo using - key "fubar". - - - -Kalt Informational [Page 16] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - JOIN #foo,&bar fubar ; Command to join channel #foo using - key "fubar" and &bar using no key. - - JOIN #foo,#bar fubar,foobar ; Command to join channel #foo using - key "fubar", and channel #bar using - key "foobar". - - JOIN #foo,#bar ; Command to join channels #foo and - #bar. - - JOIN 0 ; Leave all currently joined - channels. - - :WiZ!jto@tolsun.oulu.fi JOIN #Twilight_zone ; JOIN message from WiZ - on channel #Twilight_zone - -3.2.2 Part message - - Command: PART - Parameters: *( "," ) [ ] - - The PART command causes the user sending the message to be removed - from the list of active members for all given channels listed in the - parameter string. If a "Part Message" is given, this will be sent - instead of the default message, the nickname. This request is always - granted by the server. - - Servers MUST be able to parse arguments in the form of a list of - target, but SHOULD NOT use lists when sending PART messages to - clients. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL - ERR_NOTONCHANNEL - - Examples: - - PART #twilight_zone ; Command to leave channel - "#twilight_zone" - - PART #oz-ops,&group5 ; Command to leave both channels - "&group5" and "#oz-ops". - - :WiZ!jto@tolsun.oulu.fi PART #playzone :I lost - ; User WiZ leaving channel - "#playzone" with the message "I - lost". - - - -Kalt Informational [Page 17] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.2.3 Channel mode message - - Command: MODE - Parameters: *( ( "-" / "+" ) * * ) - - The MODE command is provided so that users may query and change the - characteristics of a channel. For more details on available modes - and their uses, see "Internet Relay Chat: Channel Management" [IRC- - CHAN]. Note that there is a maximum limit of three (3) changes per - command for modes that take a parameter. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_KEYSET - ERR_NOCHANMODES ERR_CHANOPRIVSNEEDED - ERR_USERNOTINCHANNEL ERR_UNKNOWNMODE - RPL_CHANNELMODEIS - RPL_BANLIST RPL_ENDOFBANLIST - RPL_EXCEPTLIST RPL_ENDOFEXCEPTLIST - RPL_INVITELIST RPL_ENDOFINVITELIST - RPL_UNIQOPIS - - The following examples are given to help understanding the syntax of - the MODE command, but refer to modes defined in "Internet Relay Chat: - Channel Management" [IRC-CHAN]. - - Examples: - - MODE #Finnish +imI *!*@*.fi ; Command to make #Finnish channel - moderated and 'invite-only' with user - with a hostname matching *.fi - automatically invited. - - MODE #Finnish +o Kilroy ; Command to give 'chanop' privileges - to Kilroy on channel #Finnish. - - MODE #Finnish +v Wiz ; Command to allow WiZ to speak on - #Finnish. - - MODE #Fins -s ; Command to remove 'secret' flag - from channel #Fins. - - MODE #42 +k oulu ; Command to set the channel key to - "oulu". - - MODE #42 -k oulu ; Command to remove the "oulu" - channel key on channel "#42". - - - - -Kalt Informational [Page 18] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - MODE #eu-opers +l 10 ; Command to set the limit for the - number of users on channel - "#eu-opers" to 10. - - :WiZ!jto@tolsun.oulu.fi MODE #eu-opers -l - ; User "WiZ" removing the limit for - the number of users on channel "#eu- - opers". - - MODE &oulu +b ; Command to list ban masks set for - the channel "&oulu". - - MODE &oulu +b *!*@* ; Command to prevent all users from - joining. - - MODE &oulu +b *!*@*.edu +e *!*@*.bu.edu - ; Command to prevent any user from a - hostname matching *.edu from joining, - except if matching *.bu.edu - - MODE #bu +be *!*@*.edu *!*@*.bu.edu - ; Comment to prevent any user from a - hostname matching *.edu from joining, - except if matching *.bu.edu - - MODE #meditation e ; Command to list exception masks set - for the channel "#meditation". - - MODE #meditation I ; Command to list invitations masks - set for the channel "#meditation". - - MODE !12345ircd O ; Command to ask who the channel - creator for "!12345ircd" is - -3.2.4 Topic message - - Command: TOPIC - Parameters: [ ] - - The TOPIC command is used to change or view the topic of a channel. - The topic for channel is returned if there is no - given. If the parameter is present, the topic for that - channel will be changed, if this action is allowed for the user - requesting it. If the parameter is an empty string, the - topic for that channel will be removed. - - - - - - -Kalt Informational [Page 19] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_NOTONCHANNEL - RPL_NOTOPIC RPL_TOPIC - ERR_CHANOPRIVSNEEDED ERR_NOCHANMODES - - Examples: - - :WiZ!jto@tolsun.oulu.fi TOPIC #test :New topic ; User Wiz setting the - topic. - - TOPIC #test :another topic ; Command to set the topic on #test - to "another topic". - - TOPIC #test : ; Command to clear the topic on - #test. - - TOPIC #test ; Command to check the topic for - #test. - -3.2.5 Names message - - Command: NAMES - Parameters: [ *( "," ) [ ] ] - - By using the NAMES command, a user can list all nicknames that are - visible to him. For more details on what is visible and what is not, - see "Internet Relay Chat: Channel Management" [IRC-CHAN]. The - parameter specifies which channel(s) to return information - about. There is no error reply for bad channel names. - - If no parameter is given, a list of all channels and their - occupants is returned. At the end of this list, a list of users who - are visible but either not on any channel or not on a visible channel - are listed as being on `channel' "*". - - If the parameter is specified, the request is forwarded to - that server which will generate the reply. - - Wildcards are allowed in the parameter. - - Numerics: - - ERR_TOOMANYMATCHES ERR_NOSUCHSERVER - RPL_NAMREPLY RPL_ENDOFNAMES - - - - - - -Kalt Informational [Page 20] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - NAMES #twilight_zone,#42 ; Command to list visible users on - #twilight_zone and #42 - - NAMES ; Command to list all visible - channels and users - -3.2.6 List message - - Command: LIST - Parameters: [ *( "," ) [ ] ] - - The list command is used to list channels and their topics. If the - parameter is used, only the status of that channel is - displayed. - - If the parameter is specified, the request is forwarded to - that server which will generate the reply. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_TOOMANYMATCHES ERR_NOSUCHSERVER - RPL_LIST RPL_LISTEND - - Examples: - - LIST ; Command to list all channels. - - LIST #twilight_zone,#42 ; Command to list channels - #twilight_zone and #42 - -3.2.7 Invite message - - Command: INVITE - Parameters: - - The INVITE command is used to invite a user to a channel. The - parameter is the nickname of the person to be invited to - the target channel . There is no requirement that the - channel the target user is being invited to must exist or be a valid - channel. However, if the channel exists, only members of the channel - are allowed to invite other users. When the channel has invite-only - flag set, only channel operators may issue INVITE command. - - - - - -Kalt Informational [Page 21] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Only the user inviting and the user being invited will receive - notification of the invitation. Other channel members are not - notified. (This is unlike the MODE changes, and is occasionally the - source of trouble for users.) - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_NOSUCHNICK - ERR_NOTONCHANNEL ERR_USERONCHANNEL - ERR_CHANOPRIVSNEEDED - RPL_INVITING RPL_AWAY - - Examples: - - :Angel!wings@irc.org INVITE Wiz #Dust - - ; Message to WiZ when he has been - invited by user Angel to channel - #Dust - - INVITE Wiz #Twilight_Zone ; Command to invite WiZ to - #Twilight_zone - -3.2.8 Kick command - - Command: KICK - Parameters: *( "," ) *( "," ) - [] - - The KICK command can be used to request the forced removal of a user - from a channel. It causes the to PART from the by - force. For the message to be syntactically correct, there MUST be - either one channel parameter and multiple user parameter, or as many - channel parameters as there are user parameters. If a "comment" is - given, this will be sent instead of the default message, the nickname - of the user issuing the KICK. - - The server MUST NOT send KICK messages with multiple channels or - users to clients. This is necessarily to maintain backward - compatibility with old client software. - - Numeric Replies: - - ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL - ERR_BADCHANMASK ERR_CHANOPRIVSNEEDED - ERR_USERNOTINCHANNEL ERR_NOTONCHANNEL - - - - - -Kalt Informational [Page 22] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - KICK &Melbourne Matthew ; Command to kick Matthew from - &Melbourne - - KICK #Finnish John :Speaking English - ; Command to kick John from #Finnish - using "Speaking English" as the - reason (comment). - - :WiZ!jto@tolsun.oulu.fi KICK #Finnish John - ; KICK message on channel #Finnish - from WiZ to remove John from channel - -3.3 Sending messages - - The main purpose of the IRC protocol is to provide a base for clients - to communicate with each other. PRIVMSG, NOTICE and SQUERY - (described in Section 3.5 on Service Query and Commands) are the only - messages available which actually perform delivery of a text message - from one client to another - the rest just make it possible and try - to ensure it happens in a reliable and structured manner. - -3.3.1 Private messages - - Command: PRIVMSG - Parameters: - - PRIVMSG is used to send private messages between users, as well as to - send messages to channels. is usually the nickname of - the recipient of the message, or a channel name. - - The parameter may also be a host mask (#) or server - mask ($). In both cases the server will only send the PRIVMSG - to those who have a server or host matching the mask. The mask MUST - have at least 1 (one) "." in it and no wildcards following the last - ".". This requirement exists to prevent people sending messages to - "#*" or "$*", which would broadcast to all users. Wildcards are the - '*' and '?' characters. This extension to the PRIVMSG command is - only available to operators. - - Numeric Replies: - - ERR_NORECIPIENT ERR_NOTEXTTOSEND - ERR_CANNOTSENDTOCHAN ERR_NOTOPLEVEL - ERR_WILDTOPLEVEL ERR_TOOMANYTARGETS - ERR_NOSUCHNICK - RPL_AWAY - - - -Kalt Informational [Page 23] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - :Angel!wings@irc.org PRIVMSG Wiz :Are you receiving this message ? - ; Message from Angel to Wiz. - - PRIVMSG Angel :yes I'm receiving it ! - ; Command to send a message to Angel. - - PRIVMSG jto@tolsun.oulu.fi :Hello ! - ; Command to send a message to a user - on server tolsun.oulu.fi with - username of "jto". - - PRIVMSG kalt%millennium.stealth.net@irc.stealth.net :Are you a frog? - ; Message to a user on server - irc.stealth.net with username of - "kalt", and connected from the host - millennium.stealth.net. - - PRIVMSG kalt%millennium.stealth.net :Do you like cheese? - ; Message to a user on the local - server with username of "kalt", and - connected from the host - millennium.stealth.net. - - PRIVMSG Wiz!jto@tolsun.oulu.fi :Hello ! - ; Message to the user with nickname - Wiz who is connected from the host - tolsun.oulu.fi and has the username - "jto". - - PRIVMSG $*.fi :Server tolsun.oulu.fi rebooting. - ; Message to everyone on a server - which has a name matching *.fi. - - PRIVMSG #*.edu :NSFNet is undergoing work, expect interruptions - ; Message to all users who come from - a host which has a name matching - *.edu. - -3.3.2 Notice - - Command: NOTICE - Parameters: - - The NOTICE command is used similarly to PRIVMSG. The difference - between NOTICE and PRIVMSG is that automatic replies MUST NEVER be - sent in response to a NOTICE message. This rule applies to servers - - - -Kalt Informational [Page 24] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - too - they MUST NOT send any error reply back to the client on - receipt of a notice. The object of this rule is to avoid loops - between clients automatically sending something in response to - something it received. - - This command is available to services as well as users. - - This is typically used by services, and automatons (clients with - either an AI or other interactive program controlling their actions). - - See PRIVMSG for more details on replies and examples. - -3.4 Server queries and commands - - The server query group of commands has been designed to return - information about any server which is connected to the network. - - In these queries, where a parameter appears as , wildcard - masks are usually valid. For each parameter, however, only one query - and set of replies is to be generated. In most cases, if a nickname - is given, it will mean the server to which the user is connected. - - These messages typically have little value for services, it is - therefore RECOMMENDED to forbid services from using them. - -3.4.1 Motd message - - Command: MOTD - Parameters: [ ] - - The MOTD command is used to get the "Message Of The Day" of the given - server, or current server if is omitted. - - Wildcards are allowed in the parameter. - - Numeric Replies: - RPL_MOTDSTART RPL_MOTD - RPL_ENDOFMOTD ERR_NOMOTD - -3.4.2 Lusers message - - Command: LUSERS - Parameters: [ [ ] ] - - The LUSERS command is used to get statistics about the size of the - IRC network. If no parameter is given, the reply will be about the - whole net. If a is specified, then the reply will only - - - - -Kalt Informational [Page 25] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - concern the part of the network formed by the servers matching the - mask. Finally, if the parameter is specified, the request - is forwarded to that server which will generate the reply. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - RPL_LUSERCLIENT RPL_LUSEROP - RPL_LUSERUNKOWN RPL_LUSERCHANNELS - RPL_LUSERME ERR_NOSUCHSERVER - -3.4.3 Version message - - Command: VERSION - Parameters: [ ] - - The VERSION command is used to query the version of the server - program. An optional parameter is used to query the version - of the server program which a client is not directly connected to. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER RPL_VERSION - - Examples: - - VERSION tolsun.oulu.fi ; Command to check the version of - server "tolsun.oulu.fi". - -3.4.4 Stats message - - Command: STATS - Parameters: [ [ ] ] - - The stats command is used to query statistics of certain server. If - parameter is omitted, only the end of stats reply is sent - back. - - A query may be given for any single letter which is only checked by - the destination server and is otherwise passed on by intermediate - servers, ignored and unaltered. - - Wildcards are allowed in the parameter. - - - - - -Kalt Informational [Page 26] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Except for the ones below, the list of valid queries is - implementation dependent. The standard queries below SHOULD be - supported by the server: - - l - returns a list of the server's connections, showing how - long each connection has been established and the - traffic over that connection in Kbytes and messages for - each direction; - m - returns the usage count for each of commands supported - by the server; commands for which the usage count is - zero MAY be omitted; - o - returns a list of configured privileged users, - operators; - u - returns a string showing how long the server has been - up. - - It is also RECOMMENDED that client and server access configuration be - published this way. - - Numeric Replies: - - ERR_NOSUCHSERVER - RPL_STATSLINKINFO RPL_STATSUPTIME - RPL_STATSCOMMANDS RPL_STATSOLINE - RPL_ENDOFSTATS - - Examples: - - STATS m ; Command to check the command usage - for the server you are connected to - -3.4.5 Links message - - Command: LINKS - Parameters: [ [ ] ] - - With LINKS, a user can list all servernames, which are known by the - server answering the query. The returned list of servers MUST match - the mask, or if no mask is given, the full list is returned. - - If is given in addition to , the LINKS - command is forwarded to the first server found that matches that name - (if any), and that server is then required to answer the query. - - Numeric Replies: - - ERR_NOSUCHSERVER - RPL_LINKS RPL_ENDOFLINKS - - - -Kalt Informational [Page 27] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - LINKS *.au ; Command to list all servers which - have a name that matches *.au; - - LINKS *.edu *.bu.edu ; Command to list servers matching - *.bu.edu as seen by the first server - matching *.edu. - -3.4.6 Time message - - Command: TIME - Parameters: [ ] - - The time command is used to query local time from the specified - server. If the parameter is not given, the server receiving - the command must reply to the query. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER RPL_TIME - - Examples: - TIME tolsun.oulu.fi ; check the time on the server - "tolson.oulu.fi" - -3.4.7 Connect message - - Command: CONNECT - Parameters: [ ] - - The CONNECT command can be used to request a server to try to - establish a new connection to another server immediately. CONNECT is - a privileged command and SHOULD be available only to IRC Operators. - If a is given and its mask doesn't match name of the - parsing server, the CONNECT attempt is sent to the first match of - remote server. Otherwise the CONNECT attempt is made by the server - processing the request. - - The server receiving a remote CONNECT command SHOULD generate a - WALLOPS message describing the source and target of the request. - - Numeric Replies: - - ERR_NOSUCHSERVER ERR_NOPRIVILEGES - ERR_NEEDMOREPARAMS - - - -Kalt Informational [Page 28] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - CONNECT tolsun.oulu.fi 6667 ; Command to attempt to connect local - server to tolsun.oulu.fi on port 6667 - -3.4.8 Trace message - - Command: TRACE - Parameters: [ ] - - TRACE command is used to find the route to specific server and - information about its peers. Each server that processes this command - MUST report to the sender about it. The replies from pass-through - links form a chain, which shows route to destination. After sending - this reply back, the query MUST be sent to the next server until - given server is reached. - - TRACE command is used to find the route to specific server. Each - server that processes this message MUST tell the sender about it by - sending a reply indicating it is a pass-through link, forming a chain - of replies. After sending this reply back, it MUST then send the - TRACE message to the next server until given server is reached. If - the parameter is omitted, it is RECOMMENDED that TRACE - command sends a message to the sender telling which servers the local - server has direct connection to. - - If the destination given by is an actual server, the - destination server is REQUIRED to report all servers, services and - operators which are connected to it; if the command was issued by an - operator, the server MAY also report all users which are connected to - it. If the destination given by is a nickname, then only a - reply for that nickname is given. If the parameter is - omitted, it is RECOMMENDED that the TRACE command is parsed as - targeted to the processing server. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER - - If the TRACE message is destined for another server, all - intermediate servers must return a RPL_TRACELINK reply to indicate - that the TRACE passed through it and where it is going next. - - RPL_TRACELINK - - - - - -Kalt Informational [Page 29] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - A TRACE reply may be composed of any number of the following - numeric replies. - - RPL_TRACECONNECTING RPL_TRACEHANDSHAKE - RPL_TRACEUNKNOWN RPL_TRACEOPERATOR - RPL_TRACEUSER RPL_TRACESERVER - RPL_TRACESERVICE RPL_TRACENEWTYPE - RPL_TRACECLASS RPL_TRACELOG - RPL_TRACEEND - - Examples: - - TRACE *.oulu.fi ; TRACE to a server matching - *.oulu.fi - -3.4.9 Admin command - - Command: ADMIN - Parameters: [ ] - - The admin command is used to find information about the administrator - of the given server, or current server if parameter is - omitted. Each server MUST have the ability to forward ADMIN messages - to other servers. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER - RPL_ADMINME RPL_ADMINLOC1 - RPL_ADMINLOC2 RPL_ADMINEMAIL - - Examples: - - ADMIN tolsun.oulu.fi ; request an ADMIN reply from - tolsun.oulu.fi - - ADMIN syrk ; ADMIN request for the server to - which the user syrk is connected - - - - - - - - - - - -Kalt Informational [Page 30] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.4.10 Info command - - Command: INFO - Parameters: [ ] - - The INFO command is REQUIRED to return information describing the - server: its version, when it was compiled, the patchlevel, when it - was started, and any other miscellaneous information which may be - considered to be relevant. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER - RPL_INFO RPL_ENDOFINFO - - Examples: - - INFO csd.bu.edu ; request an INFO reply from - csd.bu.edu - - INFO Angel ; request info from the server that - Angel is connected to. - -3.5 Service Query and Commands - - The service query group of commands has been designed to return - information about any service which is connected to the network. - -3.5.1 Servlist message - - Command: SERVLIST - Parameters: [ [ ] ] - - The SERVLIST command is used to list services currently connected to - the network and visible to the user issuing the command. The - optional parameters may be used to restrict the result of the query - (to matching services names, and services type). - - Numeric Replies: - - RPL_SERVLIST RPL_SERVLISTEND - - - - - - - - -Kalt Informational [Page 31] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.5.2 Squery - - Command: SQUERY - Parameters: - - The SQUERY command is used similarly to PRIVMSG. The only difference - is that the recipient MUST be a service. This is the only way for a - text message to be delivered to a service. - - See PRIVMSG for more details on replies and example. - - Examples: - - SQUERY irchelp :HELP privmsg - ; Message to the service with - nickname irchelp. - - SQUERY dict@irc.fr :fr2en blaireau - ; Message to the service with name - dict@irc.fr. - -3.6 User based queries - - User queries are a group of commands which are primarily concerned - with finding details on a particular user or group users. When using - wildcards with any of these commands, if they match, they will only - return information on users who are 'visible' to you. The visibility - of a user is determined as a combination of the user's mode and the - common set of channels you are both on. - - Although services SHOULD NOT be using this class of message, they are - allowed to. - -3.6.1 Who query - - Command: WHO - Parameters: [ [ "o" ] ] - - The WHO command is used by a client to generate a query which returns - a list of information which 'matches' the parameter given by - the client. In the absence of the parameter, all visible - (users who aren't invisible (user mode +i) and who don't have a - common channel with the requesting client) are listed. The same - result can be achieved by using a of "0" or any wildcard which - will end up matching every visible user. - - The passed to WHO is matched against users' host, server, real - name and nickname if the channel cannot be found. - - - -Kalt Informational [Page 32] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - If the "o" parameter is passed only operators are returned according - to the supplied. - - Numeric Replies: - - ERR_NOSUCHSERVER - RPL_WHOREPLY RPL_ENDOFWHO - - Examples: - - WHO *.fi ; Command to list all users who match - against "*.fi". - - WHO jto* o ; Command to list all users with a - match against "jto*" if they are an - operator. - -3.6.2 Whois query - - Command: WHOIS - Parameters: [ ] *( "," ) - - This command is used to query information about particular user. - The server will answer this command with several numeric messages - indicating different statuses of each user which matches the mask (if - you are entitled to see them). If no wildcard is present in the - , any information about that nick which you are allowed to see - is presented. - - If the parameter is specified, it sends the query to a - specific server. It is useful if you want to know how long the user - in question has been idle as only local server (i.e., the server the - user is directly connected to) knows that information, while - everything else is globally known. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NOSUCHSERVER ERR_NONICKNAMEGIVEN - RPL_WHOISUSER RPL_WHOISCHANNELS - RPL_WHOISCHANNELS RPL_WHOISSERVER - RPL_AWAY RPL_WHOISOPERATOR - RPL_WHOISIDLE ERR_NOSUCHNICK - RPL_ENDOFWHOIS - - - - - - -Kalt Informational [Page 33] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - WHOIS wiz ; return available user information - about nick WiZ - - WHOIS eff.org trillian ; ask server eff.org for user - information about trillian - -3.6.3 Whowas - - Command: WHOWAS - Parameters: *( "," ) [ [ ] ] - - Whowas asks for information about a nickname which no longer exists. - This may either be due to a nickname change or the user leaving IRC. - In response to this query, the server searches through its nickname - history, looking for any nicks which are lexically the same (no wild - card matching here). The history is searched backward, returning the - most recent entry first. If there are multiple entries, up to - replies will be returned (or all of them if no - parameter is given). If a non-positive number is passed as being - , then a full search is done. - - Wildcards are allowed in the parameter. - - Numeric Replies: - - ERR_NONICKNAMEGIVEN ERR_WASNOSUCHNICK - RPL_WHOWASUSER RPL_WHOISSERVER - RPL_ENDOFWHOWAS - - Examples: - - WHOWAS Wiz ; return all information in the nick - history about nick "WiZ"; - - WHOWAS Mermaid 9 ; return at most, the 9 most recent - entries in the nick history for - "Mermaid"; - - WHOWAS Trillian 1 *.edu ; return the most recent history for - "Trillian" from the first server - found to match "*.edu". - -3.7 Miscellaneous messages - - Messages in this category do not fit into any of the above categories - but are nonetheless still a part of and REQUIRED by the protocol. - - - -Kalt Informational [Page 34] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.7.1 Kill message - - Command: KILL - Parameters: - - The KILL command is used to cause a client-server connection to be - closed by the server which has the actual connection. Servers - generate KILL messages on nickname collisions. It MAY also be - available available to users who have the operator status. - - Clients which have automatic reconnect algorithms effectively make - this command useless since the disconnection is only brief. It does - however break the flow of data and can be used to stop large amounts - of 'flooding' from abusive users or accidents. Abusive users usually - don't care as they will reconnect promptly and resume their abusive - behaviour. To prevent this command from being abused, any user may - elect to receive KILL messages generated for others to keep an 'eye' - on would be trouble spots. - - In an arena where nicknames are REQUIRED to be globally unique at all - times, KILL messages are sent whenever 'duplicates' are detected - (that is an attempt to register two users with the same nickname) in - the hope that both of them will disappear and only 1 reappear. - - When a client is removed as the result of a KILL message, the server - SHOULD add the nickname to the list of unavailable nicknames in an - attempt to avoid clients to reuse this name immediately which is - usually the pattern of abusive behaviour often leading to useless - "KILL loops". See the "IRC Server Protocol" document [IRC-SERVER] - for more information on this procedure. - - The comment given MUST reflect the actual reason for the KILL. For - server-generated KILLs it usually is made up of details concerning - the origins of the two conflicting nicknames. For users it is left - up to them to provide an adequate reason to satisfy others who see - it. To prevent/discourage fake KILLs from being generated to hide - the identify of the KILLer, the comment also shows a 'kill-path' - which is updated by each server it passes through, each prepending - its name to the path. - - Numeric Replies: - - ERR_NOPRIVILEGES ERR_NEEDMOREPARAMS - ERR_NOSUCHNICK ERR_CANTKILLSERVER - - - - - - - -Kalt Informational [Page 35] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - NOTE: - It is RECOMMENDED that only Operators be allowed to kill other users - with KILL command. This command has been the subject of many - controversies over the years, and along with the above - recommendation, it is also widely recognized that not even operators - should be allowed to kill users on remote servers. - -3.7.2 Ping message - - Command: PING - Parameters: [ ] - - The PING command is used to test the presence of an active client or - server at the other end of the connection. Servers send a PING - message at regular intervals if no other activity detected coming - from a connection. If a connection fails to respond to a PING - message within a set amount of time, that connection is closed. A - PING message MAY be sent even if the connection is active. - - When a PING message is received, the appropriate PONG message MUST be - sent as reply to (server which sent the PING message out) - as soon as possible. If the parameter is specified, it - represents the target of the ping, and the message gets forwarded - there. - - Numeric Replies: - - ERR_NOORIGIN ERR_NOSUCHSERVER - - Examples: - - PING tolsun.oulu.fi ; Command to send a PING message to - server - - PING WiZ tolsun.oulu.fi ; Command from WiZ to send a PING - message to server "tolsun.oulu.fi" - - PING :irc.funet.fi ; Ping message sent by server - "irc.funet.fi" - - - - - - - - - - - - -Kalt Informational [Page 36] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -3.7.3 Pong message - - Command: PONG - Parameters: [ ] - - PONG message is a reply to ping message. If parameter is - given, this message MUST be forwarded to given target. The - parameter is the name of the entity who has responded to PING message - and generated this message. - - Numeric Replies: - - ERR_NOORIGIN ERR_NOSUCHSERVER - - Example: - - PONG csd.bu.edu tolsun.oulu.fi ; PONG message from csd.bu.edu to - tolsun.oulu.fi - -3.7.4 Error - - Command: ERROR - Parameters: - - The ERROR command is for use by servers when reporting a serious or - fatal error to its peers. It may also be sent from one server to - another but MUST NOT be accepted from any normal unknown clients. - - Only an ERROR message SHOULD be used for reporting errors which occur - with a server-to-server link. An ERROR message is sent to the server - at the other end (which reports it to appropriate local users and - logs) and to appropriate local users and logs. It is not to be - passed onto any other servers by a server if it is received from a - server. - - The ERROR message is also used before terminating a client - connection. - - When a server sends a received ERROR message to its operators, the - message SHOULD be encapsulated inside a NOTICE message, indicating - that the client was not responsible for the error. - - Numerics: - - None. - - - - - - -Kalt Informational [Page 37] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - ERROR :Server *.fi already exists ; ERROR message to the other server - which caused this error. - - NOTICE WiZ :ERROR from csd.bu.edu -- Server *.fi already exists - ; Same ERROR message as above but - sent to user WiZ on the other server. - -4. Optional features - - This section describes OPTIONAL messages. They are not required in a - working server implementation of the protocol described herein. In - the absence of the feature, an error reply message MUST be generated - or an unknown command error. If the message is destined for another - server to answer then it MUST be passed on (elementary parsing - REQUIRED) The allocated numerics for this are listed with the - messages below. - - From this section, only the USERHOST and ISON messages are available - to services. - -4.1 Away - - Command: AWAY - Parameters: [ ] - - With the AWAY command, clients can set an automatic reply string for - any PRIVMSG commands directed at them (not to a channel they are on). - The server sends an automatic reply to the client sending the PRIVMSG - command. The only replying server is the one to which the sending - client is connected to. - - The AWAY command is used either with one parameter, to set an AWAY - message, or with no parameters, to remove the AWAY message. - - Because of its high cost (memory and bandwidth wise), the AWAY - message SHOULD only be used for client-server communication. A - server MAY choose to silently ignore AWAY messages received from - other servers. To update the away status of a client across servers, - the user mode 'a' SHOULD be used instead. (See Section 3.1.5) - - Numeric Replies: - - RPL_UNAWAY RPL_NOWAWAY - - - - - - -Kalt Informational [Page 38] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Example: - - AWAY :Gone to lunch. Back in 5 ; Command to set away message to - "Gone to lunch. Back in 5". - -4.2 Rehash message - - Command: REHASH - Parameters: None - - The rehash command is an administrative command which can be used by - an operator to force the server to re-read and process its - configuration file. - - Numeric Replies: - - RPL_REHASHING ERR_NOPRIVILEGES - - - Example: - - REHASH ; message from user with operator - status to server asking it to reread - its configuration file. - -4.3 Die message - - Command: DIE - Parameters: None - - An operator can use the DIE command to shutdown the server. This - message is optional since it may be viewed as a risk to allow - arbitrary people to connect to a server as an operator and execute - this command. - - The DIE command MUST always be fully processed by the server to which - the sending client is connected and MUST NOT be passed onto other - connected servers. - - Numeric Replies: - - ERR_NOPRIVILEGES - - Example: - - DIE ; no parameters required. - - - - - -Kalt Informational [Page 39] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - -4.4 Restart message - - Command: RESTART - Parameters: None - - An operator can use the restart command to force the server to - restart itself. This message is optional since it may be viewed as a - risk to allow arbitrary people to connect to a server as an operator - and execute this command, causing (at least) a disruption to service. - - The RESTART command MUST always be fully processed by the server to - which the sending client is connected and MUST NOT be passed onto - other connected servers. - - Numeric Replies: - - ERR_NOPRIVILEGES - - Example: - - RESTART ; no parameters required. - -4.5 Summon message - - Command: SUMMON - Parameters: [ [ ] ] - - The SUMMON command can be used to give users who are on a host - running an IRC server a message asking them to please join IRC. This - message is only sent if the target server (a) has SUMMON enabled, (b) - the user is logged in and (c) the server process can write to the - user's tty (or similar). - - If no parameter is given it tries to summon from the - server the client is connected to is assumed as the target. - - If summon is not enabled in a server, it MUST return the - ERR_SUMMONDISABLED numeric. - - Numeric Replies: - - ERR_NORECIPIENT ERR_FILEERROR - ERR_NOLOGIN ERR_NOSUCHSERVER - ERR_SUMMONDISABLED RPL_SUMMONING - - - - - - - -Kalt Informational [Page 40] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - Examples: - - SUMMON jto ; summon user jto on the server's - host - - SUMMON jto tolsun.oulu.fi ; summon user jto on the host which a - server named "tolsun.oulu.fi" is - running. - -4.6 Users - - Command: USERS - Parameters: [ ] - - The USERS command returns a list of users logged into the server in a - format similar to the UNIX commands who(1), rusers(1) and finger(1). - If disabled, the correct numeric MUST be returned to indicate this. - - Because of the security implications of such a command, it SHOULD be - disabled by default in server implementations. Enabling it SHOULD - require recompiling the server or some equivalent change rather than - simply toggling an option and restarting the server. The procedure - to enable this command SHOULD also include suitable large comments. - - Numeric Replies: - - ERR_NOSUCHSERVER ERR_FILEERROR - RPL_USERSSTART RPL_USERS - RPL_NOUSERS RPL_ENDOFUSERS - ERR_USERSDISABLED - - Disabled Reply: - - ERR_USERSDISABLED - - Example: - - USERS eff.org ; request a list of users logged in - on server eff.org - -4.7 Operwall message - - Command: WALLOPS - Parameters: - - The WALLOPS command is used to send a message to all currently - connected users who have set the 'w' user mode for themselves. (See - Section 3.1.5 "User modes"). - - - -Kalt Informational [Page 41] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - After implementing WALLOPS as a user command it was found that it was - often and commonly abused as a means of sending a message to a lot of - people. Due to this, it is RECOMMENDED that the implementation of - WALLOPS allows and recognizes only servers as the originators of - WALLOPS. - - Numeric Replies: - - ERR_NEEDMOREPARAMS - - Example: - - :csd.bu.edu WALLOPS :Connect '*.uiuc.edu 6667' from Joshua ; WALLOPS - message from csd.bu.edu announcing a - CONNECT message it received from - Joshua and acted upon. - -4.8 Userhost message - - Command: USERHOST - Parameters: *( SPACE ) - - The USERHOST command takes a list of up to 5 nicknames, each - separated by a space character and returns a list of information - about each nickname that it found. The returned list has each reply - separated by a space. - - Numeric Replies: - - RPL_USERHOST ERR_NEEDMOREPARAMS - - Example: - - USERHOST Wiz Michael syrk ; USERHOST request for information on - nicks "Wiz", "Michael", and "syrk" - - :ircd.stealth.net 302 yournick :syrk=+syrk@millennium.stealth.net - ; Reply for user syrk - -4.9 Ison message - - Command: ISON - Parameters: *( SPACE ) - - The ISON command was implemented to provide a quick and efficient - means to get a response about whether a given nickname was currently - on IRC. ISON only takes one (1) type of parameter: a space-separated - list of nicks. For each nickname in the list that is present, the - - - -Kalt Informational [Page 42] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - server adds that to its reply string. Thus the reply string may - return empty (none of the given nicks are present), an exact copy of - the parameter string (all of them present) or any other subset of the - set of nicks given in the parameter. The only limit on the number of - nicks that may be checked is that the combined length MUST NOT be too - large as to cause the server to chop it off so it fits in 512 - characters. - - ISON is only processed by the server local to the client sending the - command and thus not passed onto other servers for further - processing. - - Numeric Replies: - - RPL_ISON ERR_NEEDMOREPARAMS - - Example: - - ISON phone trillian WiZ jarlek Avalon Angel Monstah syrk - ; Sample ISON request for 7 nicks. - -5. Replies - - The following is a list of numeric replies which are generated in - response to the commands given above. Each numeric is given with its - number, name and reply string. - -5.1 Command responses - - Numerics in the range from 001 to 099 are used for client-server - connections only and should never travel between servers. Replies - generated in the response to commands are found in the range from 200 - to 399. - - 001 RPL_WELCOME - "Welcome to the Internet Relay Network - !@" - 002 RPL_YOURHOST - "Your host is , running version " - 003 RPL_CREATED - "This server was created " - 004 RPL_MYINFO - " - " - - - The server sends Replies 001 to 004 to a user upon - successful registration. - - - - -Kalt Informational [Page 43] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 005 RPL_BOUNCE - "Try server , port " - - - Sent by the server to a user to suggest an alternative - server. This is often used when the connection is - refused because the server is already full. - - 302 RPL_USERHOST - ":*1 *( " " )" - - - Reply format used by USERHOST to list replies to - the query list. The reply string is composed as - follows: - - reply = nickname [ "*" ] "=" ( "+" / "-" ) hostname - - The '*' indicates whether the client has registered - as an Operator. The '-' or '+' characters represent - whether the client has set an AWAY message or not - respectively. - - 303 RPL_ISON - ":*1 *( " " )" - - - Reply format used by ISON to list replies to the - query list. - - 301 RPL_AWAY - " :" - 305 RPL_UNAWAY - ":You are no longer marked as being away" - 306 RPL_NOWAWAY - ":You have been marked as being away" - - - These replies are used with the AWAY command (if - allowed). RPL_AWAY is sent to any client sending a - PRIVMSG to a client which is away. RPL_AWAY is only - sent by the server to which the client is connected. - Replies RPL_UNAWAY and RPL_NOWAWAY are sent when the - client removes and sets an AWAY message. - - 311 RPL_WHOISUSER - " * :" - 312 RPL_WHOISSERVER - " :" - 313 RPL_WHOISOPERATOR - " :is an IRC operator" - - - - -Kalt Informational [Page 44] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 317 RPL_WHOISIDLE - " :seconds idle" - 318 RPL_ENDOFWHOIS - " :End of WHOIS list" - 319 RPL_WHOISCHANNELS - " :*( ( "@" / "+" ) " " )" - - - Replies 311 - 313, 317 - 319 are all replies - generated in response to a WHOIS message. Given that - there are enough parameters present, the answering - server MUST either formulate a reply out of the above - numerics (if the query nick is found) or return an - error reply. The '*' in RPL_WHOISUSER is there as - the literal character and not as a wild card. For - each reply set, only RPL_WHOISCHANNELS may appear - more than once (for long lists of channel names). - The '@' and '+' characters next to the channel name - indicate whether a client is a channel operator or - has been granted permission to speak on a moderated - channel. The RPL_ENDOFWHOIS reply is used to mark - the end of processing a WHOIS message. - - 314 RPL_WHOWASUSER - " * :" - 369 RPL_ENDOFWHOWAS - " :End of WHOWAS" - - - When replying to a WHOWAS message, a server MUST use - the replies RPL_WHOWASUSER, RPL_WHOISSERVER or - ERR_WASNOSUCHNICK for each nickname in the presented - list. At the end of all reply batches, there MUST - be RPL_ENDOFWHOWAS (even if there was only one reply - and it was an error). - - 321 RPL_LISTSTART - Obsolete. Not used. - - 322 RPL_LIST - " <# visible> :" - 323 RPL_LISTEND - ":End of LIST" - - - Replies RPL_LIST, RPL_LISTEND mark the actual replies - with data and end of the server's response to a LIST - command. If there are no channels available to return, - only the end reply MUST be sent. - - - - - -Kalt Informational [Page 45] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 325 RPL_UNIQOPIS - " " - - 324 RPL_CHANNELMODEIS - " " - - 331 RPL_NOTOPIC - " :No topic is set" - 332 RPL_TOPIC - " :" - - - When sending a TOPIC message to determine the - channel topic, one of two replies is sent. If - the topic is set, RPL_TOPIC is sent back else - RPL_NOTOPIC. - - 341 RPL_INVITING - " " - - - Returned by the server to indicate that the - attempted INVITE message was successful and is - being passed onto the end client. - - 342 RPL_SUMMONING - " :Summoning user to IRC" - - - Returned by a server answering a SUMMON message to - indicate that it is summoning that user. - - 346 RPL_INVITELIST - " " - 347 RPL_ENDOFINVITELIST - " :End of channel invite list" - - - When listing the 'invitations masks' for a given channel, - a server is required to send the list back using the - RPL_INVITELIST and RPL_ENDOFINVITELIST messages. A - separate RPL_INVITELIST is sent for each active mask. - After the masks have been listed (or if none present) a - RPL_ENDOFINVITELIST MUST be sent. - - 348 RPL_EXCEPTLIST - " " - 349 RPL_ENDOFEXCEPTLIST - " :End of channel exception list" - - - - - - -Kalt Informational [Page 46] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - - When listing the 'exception masks' for a given channel, - a server is required to send the list back using the - RPL_EXCEPTLIST and RPL_ENDOFEXCEPTLIST messages. A - separate RPL_EXCEPTLIST is sent for each active mask. - After the masks have been listed (or if none present) - a RPL_ENDOFEXCEPTLIST MUST be sent. - - 351 RPL_VERSION - ". :" - - - Reply by the server showing its version details. - The is the version of the software being - used (including any patchlevel revisions) and the - is used to indicate if the server is - running in "debug mode". - - The "comments" field may contain any comments about - the version or further version details. - - 352 RPL_WHOREPLY - " - ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] - : " - - 315 RPL_ENDOFWHO - " :End of WHO list" - - - The RPL_WHOREPLY and RPL_ENDOFWHO pair are used - to answer a WHO message. The RPL_WHOREPLY is only - sent if there is an appropriate match to the WHO - query. If there is a list of parameters supplied - with a WHO message, a RPL_ENDOFWHO MUST be sent - after processing each list item with being - the item. - - 353 RPL_NAMREPLY - "( "=" / "*" / "@" ) - :[ "@" / "+" ] *( " " [ "@" / "+" ] ) - - "@" is used for secret channels, "*" for private - channels, and "=" for others (public channels). - - 366 RPL_ENDOFNAMES - " :End of NAMES list" - - - To reply to a NAMES message, a reply pair consisting - of RPL_NAMREPLY and RPL_ENDOFNAMES is sent by the - server back to the client. If there is no channel - found as in the query, then only RPL_ENDOFNAMES is - - - -Kalt Informational [Page 47] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - returned. The exception to this is when a NAMES - message is sent with no parameters and all visible - channels and contents are sent back in a series of - RPL_NAMEREPLY messages with a RPL_ENDOFNAMES to mark - the end. - - 364 RPL_LINKS - " : " - 365 RPL_ENDOFLINKS - " :End of LINKS list" - - - In replying to the LINKS message, a server MUST send - replies back using the RPL_LINKS numeric and mark the - end of the list using an RPL_ENDOFLINKS reply. - - 367 RPL_BANLIST - " " - 368 RPL_ENDOFBANLIST - " :End of channel ban list" - - - When listing the active 'bans' for a given channel, - a server is required to send the list back using the - RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate - RPL_BANLIST is sent for each active banmask. After the - banmasks have been listed (or if none present) a - RPL_ENDOFBANLIST MUST be sent. - - 371 RPL_INFO - ":" - 374 RPL_ENDOFINFO - ":End of INFO list" - - - A server responding to an INFO message is required to - send all its 'info' in a series of RPL_INFO messages - with a RPL_ENDOFINFO reply to indicate the end of the - replies. - - 375 RPL_MOTDSTART - ":- Message of the day - " - 372 RPL_MOTD - ":- " - 376 RPL_ENDOFMOTD - ":End of MOTD command" - - - When responding to the MOTD message and the MOTD file - is found, the file is displayed line by line, with - each line no longer than 80 characters, using - - - - -Kalt Informational [Page 48] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - RPL_MOTD format replies. These MUST be surrounded - by a RPL_MOTDSTART (before the RPL_MOTDs) and an - RPL_ENDOFMOTD (after). - - 381 RPL_YOUREOPER - ":You are now an IRC operator" - - - RPL_YOUREOPER is sent back to a client which has - just successfully issued an OPER message and gained - operator status. - - 382 RPL_REHASHING - " :Rehashing" - - - If the REHASH option is used and an operator sends - a REHASH message, an RPL_REHASHING is sent back to - the operator. - - 383 RPL_YOURESERVICE - "You are service " - - - Sent by the server to a service upon successful - registration. - - 391 RPL_TIME - " :" - - - When replying to the TIME message, a server MUST send - the reply using the RPL_TIME format above. The string - showing the time need only contain the correct day and - time there. There is no further requirement for the - time string. - - 392 RPL_USERSSTART - ":UserID Terminal Host" - 393 RPL_USERS - ": " - 394 RPL_ENDOFUSERS - ":End of users" - 395 RPL_NOUSERS - ":Nobody logged in" - - - If the USERS message is handled by a server, the - replies RPL_USERSTART, RPL_USERS, RPL_ENDOFUSERS and - RPL_NOUSERS are used. RPL_USERSSTART MUST be sent - first, following by either a sequence of RPL_USERS - or a single RPL_NOUSER. Following this is - RPL_ENDOFUSERS. - - - -Kalt Informational [Page 49] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - 200 RPL_TRACELINK - "Link - V - - " - 201 RPL_TRACECONNECTING - "Try. " - 202 RPL_TRACEHANDSHAKE - "H.S. " - 203 RPL_TRACEUNKNOWN - "???? []" - 204 RPL_TRACEOPERATOR - "Oper " - 205 RPL_TRACEUSER - "User " - 206 RPL_TRACESERVER - "Serv S C - @ V" - 207 RPL_TRACESERVICE - "Service " - 208 RPL_TRACENEWTYPE - " 0 " - 209 RPL_TRACECLASS - "Class " - 210 RPL_TRACERECONNECT - Unused. - 261 RPL_TRACELOG - "File " - 262 RPL_TRACEEND - " :End of TRACE" - - - The RPL_TRACE* are all returned by the server in - response to the TRACE message. How many are - returned is dependent on the TRACE message and - whether it was sent by an operator or not. There - is no predefined order for which occurs first. - Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and - RPL_TRACEHANDSHAKE are all used for connections - which have not been fully established and are either - unknown, still attempting to connect or in the - process of completing the 'server handshake'. - RPL_TRACELINK is sent by any server which handles - a TRACE message and has to pass it on to another - server. The list of RPL_TRACELINKs sent in - response to a TRACE command traversing the IRC - network should reflect the actual connectivity of - the servers themselves along that path. - - - - -Kalt Informational [Page 50] - -RFC 2812 Internet Relay Chat: Client Protocol April 2000 - - - RPL_TRACENEWTYPE is to be used for any connection - which does not fit in the other categories but is - being displayed anyway. - RPL_TRACEEND is sent to indicate the end of the list. - - 211 RPL_STATSLINKINFO - " - -