operator: iscm, and case-mapping switch for $ial and possibly $ialchan and others

Just as $sorttok offers a 'c' sort method which acts differently based on the value of the $prefix identifier, it can be difficult to accurately match $banmask or identify which nicks in the IAL match a specific mask, without functions which recognize case-insensitivity the same way the server does.

Apparently the creators of rfc1459 decided that it was useful to have a weird definition of what "case-insensitive" means. For most servers, the 005 numeric contains CASEMAPPING=rfc1459 which, in addition to treating the A-Z and a-z ranges as upper/lower case equivalent nicks, thinks there are now extra case-insensitive upper/lower pairs:

123 { 91 [
124 | 92 \
125 } 93 ]
126 ~ 94 ^

There apparently is also a "strict-rfc1459" which recognizes all the pairs except for the 126/94 match.

For scripts trying to see which nicks match a new $banmask being added or deleted, the script can return the wrong results if the $banmask contains contains any of these 8 (or 6) characters and there are nicks which are using the opposite character of that pair.

For example, a script like this should remove a new banmask if it matches yourself:

on @*:BAN:#channelname:{
  if ($banmask iswm $address($me,5)) { mode $chan -b $banmask }

For the most part it would work, however, if I change my nick and someone sets a banmask:

/nick maroon{
/mode #channelname +b maroon[!*@*

... the script doesn't think that $banmask matches $address($me,5), because it doesn't match me in the real world.

//echo -a $ial(maroon[!*@*,0)

Likewise, if the script were to loop through the IAL checking to see how many nicks match this $banmask, the answer would be zero because $ial is using the real-world definition of case-insensitive instead of looking at CASEMAPPING= and acting accordingly. It would be zero because using the { prevents anyone else from using the maroon[ nick.

/kick #channelname maroon[

This kick, using a fake case-insensitive match, matches against maroon{ and it kicks maroon{ from channel. And because the { and [ are also matched by the channel in evaluating the +b modes, it blocks the maroon{ nick from re-entering too.

This has the potential to affect people using "normal" nicks, because - unless it's a bug that is going to be fixed - freenode makes the abnormal case-insensitive matches in the userid too. The +b banmask matches the ~ in nick!~userid@host, where the ~ is assigned to nicks which didn't answer the identd check at port 59.

/mode #channelname +b *!^*@*

This means that the above mask bans everyone who did not answer the identd handshake, and it would be easy for scripts to not notice that this ban was affecting a lot of people. I wasn't able to find any @vhosts containing any of these 8 characters, so I don't know whether the definition extends to the entire address, or whether this was supposed to be applying only to the $nick.


I'm assuming that there's only 3 possible strings for CASEMAPPING=, and there shouldn't be a need for $ial() and $ialchan() to *not* behaves according to the CASEMAPPING= setting. If there's no such keyword found, or it's some unknown new string, I'm thinking it should retain the current =ascii behavior.

It's possible this may also need to affect $level /auser /ruser etc, except those have the potential to affect nicks at all networks regardless where the mask was created.

some kind of iswmCM or isCM identifier would avoid corrupting the current "iswm" identifier which should not see this weird definition of case-insensitive, but that's the only place I can think of which normally does NOT need to see the altered settings, unless there are scripts needing to check "if (maroon} == maroon])".

Most networks I checked use the CASEMAPPING=rfc1459 setting, with the exception being SwiftIRC which has CASEMAPPING=ascii

section 4.1