I’m trying to code my own IRC server. I’m referencing the IRC RFC but it’s a little confusing to me. If I were to go strictly off the RFC, I don’t think any of the popular clients would work with my server, like mIRC. For example, the RFC says that the server should respond to a successful MODE command one of the following numeric responses:RPL_BANLIST, RPL_CHANNELMODEIS, RPL_ENDOFBANLIST, RPL_UMODEIS. This would lead me to believe that on a successful user mode change, I’d respond with RPL_UMODEIS, although the RFC doesn’t seem to explicitly state so.
But, when I check the source code to another open source IRC server, I see that it responds with a non-numeric command of ‘MODE’. It just echos back the MODE command it looks like.
How are you supposed to respond to the MODE command? Is there a better formatted RFC that has a simple command and response chart, or something?
RFC 1459 is famously sparse. It does not tell you everything you need to know to write a server.
In this case, what’s missing is the distinction between a
MODEcommand that queries an existing mode, and aMODEcommand that sets a new mode. In the case of a mode query, a client will receive a numeric reply that indicates the existing mode; in the case of altering a mode, a client will not receive a direct numeric reply unless there was an error. However, if the mode was successfully altered, then a client will recieve aMODEfrom the server informing it of the change.So for example, if the client’s nick is
fooand it sends:then this is querying its current usermode – it will expect a
RPL_UMODEISreply like:If the client then sends:
then this is altering its usermode – it will either get a numeric error like
ERR_USERSDONTMATCHor an acknowledgement of the mode change:Note that this acknowledgement is technically not a direct reply to the
MODE– it’s the server informing the client of a relevant change in its state, which happens to have been triggered by a client command.A similar situation exists with channel modes. If a client queries the current channel modes with:
then it will expect a
RPL_CHANNELMODEISresponse containing the current “simple” channel modes, and perhaps aRPL_CREATIONTIMEresponse giving the channel creation time. If it queries for the current ban list with:then should get zero or more
RPL_BANLISTresponses, followed by aRPL_ENDOFBANLIST.If instead a client tries to change a channel mode:
then the direct reply will either be an error reply or nothing; and if the channel mode was actually changed, it will see the
MODEcommand echoed back. In the latter case the successfulMODEcommand will also be sent to the other members of the channel – this helps to illustrate that it’s not really a direct reply to the initialMODEcommand, but an indirect response to it.