diff -u -r -N ircu2.10-lain-vanilla/doc/example.conf ircu2.10-lain/doc/example.conf
--- ircu2.10-lain-vanilla/doc/example.conf	Fri May 25 01:57:26 2001
+++ ircu2.10-lain/doc/example.conf	Sun Jun  3 02:31:55 2001
@@ -1,27 +1,22 @@
-# ircd.conf  configuration file for ircd version ircu2.10-hidoinet-1.0
+# ircd example.conf configuration file for ircd Lain 1.1.x
+# Based on the original Undernet u2.10.10 example.conf
 #
-# Written by Niels <niels@undernet.org>, based on the original example.conf,
-# server code and some real-life (ahem) experience.
+# Please visit http://coder-com.undernet.org/ for information and 
+# files specific to the original u2.10.10 ircd
 #
 # Thanks and credits to: Run, Trillian, Cym, Morrissey, Chaos, Flynn,
 #                        Xorath, WildThang, Mmmm, SeKs, Ghostwolf and
 #                        all other Undernet IRC Admins and Operators,
 #                        and programmers working on the Undernet ircd.
 #
-# HidoiNET modifications by Rurouni Dreamer and Sivis <irc@hidoinet.org>
-
-# This is an example of the configuration file used by the Hidoinet IRCD
-# Modified from the original Undernet IRCD example config
-#
-# This example config file is based on a (fictious) server with a 
-# connection to the HidoiNET IRC Network. 
+# Lain is designed by Tero 'Sivis' Nybacka, and thanks go to all people 
+# working on the original QuakeNet Patch, especially the father of QuakeNet
+# Patch, Darren Coleman. Additional thanks are extended to all people of 
+# the QuakeNet development committee and all others who have been working
+# with Lain development.
 #
-# Do NOT try to start IRCD without modifying this file properly, according
-# to the instructions you have been given. If you're unsure, ask first. 
-# 
-# Incorrect configuration settings may be a cause for removal of a 
-# badly configured server link. We're not trying to be bitchy, but the
-# network is a lot more fun when it works
+# Lain and QuakeNet/B2IRC modifications to the example config were 
+# written by Antti 'Vekotin' Eturautti
 #
 # All configuration options start with a letter identifying the option,
 # and a colon separated list of options. An asterisk indicates an
@@ -36,7 +31,9 @@
 # of the machine that the server is run on. For example, the host can
 # have ``veer.cs.vu.nl'' as FQDN, and ``Amsterdam.NL.EU.undernet.org'' as
 # server name.
-# A ``server mask'' is something like '*.hidoinet.org''
+# A ``server mask'' is something like '*.EU.UnderNet.org'', which is
+# matched by 'Amsterdam.NL.EU.undernet.org' but not by
+# 'Manhattan.KS.US.undernet.org'.
 
 
 # First some information about the server.
@@ -52,91 +49,121 @@
 #
 # The <server port> is no longer used.
 # Ports need to be specified with a P: line, see below.
-# At some point in the future we may want to use the port value for
-# server capacity. --Bleep
 #
 # Note that <server numeric> has to be unique on the network your server
 # is running on, must be between 1 and 4096, and is not updated on a rehash.
 # Be very sure of this - the server will not link with an incorrect numeric
-# 
+M:irc1.fi.quakenet.org:11.22.33.44:Tiimipeli/Peliportti QuakeNet server:0:123
 
-M:london.uk.hidoinet.org:*:Hidoinet London LEAF, England:0:10
 
-#
 # This sets information that can be retrieved with the /ADMIN command.
 # It should contain at least an admin Email contact address.
 # A:<line 1>:<line 2>:<line 3>
-#
-# On HidoiNET, line 2 must contain the same text on all servers, currently
-# 'HidoiNET Project IRC Server'. It is recommended that line 3 contains
-# the email address for the admin of this ircd, preferrably using a 
-# @hidoinet.org format email address
+# 
+# Line 1 should contain information on the company/organization sponsoring
+# the server, line 2 should have information about the network itself, for
+# example 'QuakeNet IRC server' or 'B2IRC Network'. Line 3 should have 
+# the email address of the administrator
+A:Tiimipeli/Peliportti:QuakeNet IRC server:Admin <vekotin@quakenet.eu.org>
 
-A:London anime peoples club:HidoiNET Project IRC Server:IRC Admin <adminguy@hid
-oinet.org>
 
-# E-line is used for configuring the patch features.
+# The E: line specifies configuration options for Lain specific features
+#
 # Each number represents one patch feature and values are '0' = off,
-# '1' = on, '2' = usage is wallopped, '3' = usage is sent as local server notice
+# '1' = on, '2' = usage is wallopped, '3' = usage is sent to IRCops as 
+# local server notice
+
 #
 # Unless specified otherwise, you should usually leave these as defaults
+# on QuakeNet and B2IRC
 #
-# +---------------- Opers can set umode +k (Channel Service)
-# |+--------------- Opers can set umode +X (Extended oper)
-# ||+-------------- ..to join invite only channels
-# |||+------------- ..to join keyed channels
-# ||||+------------ ..to join channels if banned
-# |||||+----------- ..to join full channels
-# ||||||+---------- ..to kill +k clients
-# |||||||+--------- ..to deop +k clients
-# ||||||||+-------- ..to kick +k clients
-# |||||||||+------- Use fakehosts (F-lines) [This is not wallopped]
-# ||||||||||+------ Opers can message +n channels externally
-# |||||||||||+----- Opers can speak on moderated channels [This is not wallopped]
-# ||||||||||||+---- Opers can use servmode command
-# |||||||||||||+--- Opers can change their host dynamically
-# ||||||||||||||+-- Allow users to SETHOST passworded S:lines
+# +- Opers can set umode +k (Channel Service)
+# |+- Opers can set umode +X (Extended oper)
+# ||+-  ..to join invite only channels
+# |||+-  ..to join keyed channels
+# ||||+-  ..to join channels if banned
+# |||||+-  ..to join full channels
+# ||||||+-  ..to kill +k clients
+# |||||||+-  ..to deop +k clients
+# ||||||||+-  ..to kick +k clients
+# |||||||||+- Use fakehosts (F-lines) [This is not wallopped]
+# ||||||||||+- Opers can message +n channels externally
+# |||||||||||+- Opers can speak on moderated channels [This is not wallopped]
+# ||||||||||||+- Opers can use servmode command
+# |||||||||||||+- Opers can change their host dynamically
+# ||||||||||||||+- Allow users to SETHOST passworded S:lines
 # |||||||||||||||+- Opers will not exceed their SendQ [This is not wallopped]
-# ||||||||||||||||+ Opers have smaller penalty when flooding [This is not wallopped]
+# ||||||||||||||||+- Opers have smaller penalty when flooding [This is not wallopped]
 # |||||||||||||||||
 E:12112121112111111
 
-# F-lines are used to define fakehosts for certain users
-# line is in format: F:<ident>:<original host>:<fakehost>
-# Wildcards are not allowed
+
+# F-lines are used to define automatic fakehosts for users. Also see S: 
+# lines below, which are used for manual host/ident change. 
+#
+# As a comparison, F: lines require you to have a static IP/host, 
+# and will not allow you to change ident, but they are always 
+# automatically activated on connect. S: lines are activated manually
+#
+# F:<ident>:<original host>:<fakehost>
+# Wildcards are not allowed, original host may either be a hostname or 
+# an ip address - IP addresses will be resolved as required.
 #
 # Fakehosts are meant primarily for operator security. The idea is that
 # an oper using fakehost "localhost" will not be the victim of active
-# DDOS attacks as easily, for example. Do not provide F: lines for normal
-# users in any situations.
+# DDOS attacks as easily, for example. S: line fakehosts can also be used 
+# by operators to go "undercover", for example when cases of network abuse 
+# need to be investigated.
+#
+# Operators may always check the real ip of any user with /userip and
+# /check, but even so, F: and S: lines shouldn't generally be provided to
+# normal users except in some special cases.
+# 
+#F:user:real.host.org:his.elite.fake.host
 
-F:user:real.host.org:his.elite.fake.host
 
+# S: lines permit users and operators to change to fakehosts manually after 
+# connect. Activating an S: line also enables opers to change their ident
+#
+# There are two types of S: lines - operator and user S: lines. Operators 
+# may activate any operator S: line once opered, with 
+# /sethost ident fakehost
+#
+# User S: lines are more limited - ident cannot be changed, and activating 
+# an S: line requires a password, which is defined in this configuration.
+# A user S: line is activated with /sethost fakehost password
+# 
+# An example oper S: line:
+#S:my.cool.fakehost
 #
+# An example user S: line
+#S:funny.fakehost:mypassword
+
+
 # All connections to the server are associated with a certain ``connection
 # class'', be they incoming or outgoing (initiated by the server), be they
 # clients, servers or Martians. (Note that ircd doesn't have direct support
 # for Martians (yet?); they will have to register as normal users. ;-)
 # Take the following Y: lines only as a guide.
 # Y:<class>:<ping freq>:<connect freq>:<maximum links>:<sendq size>
-
+#
 # Server classes: 90 = all your uplinks for who you do not wish to hub;
 # else in classes 80 and/or 70.
 # 50 = leaf servers (only used if your server is a hub)
-
-Y:90:90:300:1:1700000
-Y:80:90:300:1:1700000
+Y:90:90:300:1:3400000
+Y:80:90:300:1:3400000
 Y:70:90:300:1:1700000
-Y:50:90:300:10:1700000
+Y:50:90:300:20:3400000
 
-# Client classes. 10 = locals; 2 = for all .net and .com that are not
-# in Europe; 1 = for everybody.
+# Client classes. 10 = locals; 1 = for everybody
+#
+# See the original Undernet u2.10.10 example.conf for more detailed
+# configuration options for Y: lines
+
+Y:10:90:0:50:160000
+Y:1:90:0:250:160000
 
-Y:10:90:0:100:160000
-Y:2:90:0:5:80000
-Y:1:90:0:400:160000
 
-#
 # To allow clients to connect, they need authorization. This can be
 # done based on hostmask, address mask, and/or with a password.
 # With intelligent use of classes and the maxconnections field in the
@@ -144,7 +171,13 @@
 # domains in the same toplevel, thus setting up some sort of 'reverse
 # K: line'.
 # I:<IP mask or crap to force resolving>:<opt passwd>:<hostmask>::<class>
-
+#
+# You can ignore the following technical description in most cases for 
+# QuakeNet and B2IRC, and probably almost everywhere else too, as
+# separating users into classes based on geographical location isn't
+# much used anymore. The specifications and examples are here though, 
+# for anyone who wants to play around more
+#
 # Technical description (for examples, see below):
 # For every connecting client, the IP-number is know.  A reverse lookup
 # on this IP-number is done to get the (/all) hostname(s).
@@ -165,133 +198,81 @@
 # match this I: line:
 # I:jolan.ppro::foobar::1
 # Finally, I: lines with empty <IP mask ..> or <hostmask> fields are skipped.
-
+#
 # This is the 'fallback' entry. All .uk, .nl, and all unresolved are
 # in these two lines.
 # By using two different lines, multiple connections from a single IP
 # are only allowed from hostnames which have both valid forward and
 # reverse DNS mappings.
-
-#
-# For a default HidoiNET configuration, we are not separating users in classes
-# based on geographical location. If and when needed, more complex configuratio
-ns
-# may be taken to use. In the examples below, we have simply commented out
-# any options not in use in a simple configuration.
 #
-
+# More examples are once again available in the original undernet 
+# example.conf. Here, we'll simply define everybody into class 1
 I:*@*:1:Unresolved::1
 I:Resolved::*@*::1
 
-# If you don't want unresolved dudes to be able to connect to your
-# server, use just:
-# I:NotMatchingCrap::*@*::1
-
-# Here, take care of all American ISPs.
-#I:Resolved::*@*.com::2
-#I:Resolved::*@*.net::2
-
-# Now list all the .com / .net domains that you wish to have access...
-# actually it's less work to do it this way than to do it the other
-# way around - K: lining every single ISP in the US.
-# I wish people in Holland just got a .nl domain, and not try to be
-# cool and use .com...
-#I:Resolved::*@*.wirehub.net::1
-#I:Resolved::*@*.planete.net::1
-#I:Resolved::*@*.ivg.com::1
-#I:Resolved::*@*.ib.com::1
-#I:Resolved::*@*.ibm.net::1
-#I:Resolved::*@*.hydro.com::1
-#I:Resolved::*@*.NL.net::1
-
-# You can request a more complete listing, including the "list of standard
-# K-lines" from the Routing Committee; it will also be sent to you if
-# you apply for a server and get accepted.
-
 # Ourselves - this makes sure that we can get in, no matter how full
 # the server is (hopefully).
-I:*@193.37.*::*@*.london.ac.uk::10
+#I:*@212.246.228.*::*@*::10
 
-# You can put a digit (0..9) in the password field, which will make ircd
-# only accept a client when the total number of connections to the network
-# from the same IP number doesn't exceed this number.
-# The following example would accept at most one connection per IP number
-# from "*.swipnet.se" and at most two connections from dial up accounts
-# that have "dial??.*" as host mask:
-# I:Resolved:1:*@*.swipnet.se::1
-# I:Resolved:2:*@dial??.*::1
 
-#
 # It is possible to show a different Message of the Day to a connecting
 # client depending on its origin.
-#
-# These T: lines are generally not used on HidoiNET, and there should not
-# be any need for them, unless very special conditions apply.
-#
 # T:<hostmask>:<path to motd file>
-
-# DPATH/net_com.motd contains a special MOTD where users are encouraged
-# to register their domains and get their own I: lines if they're in
-# Europe, or move to US.UnderNet.org if they're in the USA.
+#
+# There's no use for these usually on QuakeNet or B2IRC, so you can skip
+# this part as well. The Undernet example.conf contains more detailed 
+# examples for this configuration option as well
 #T:*.net:net_com.motd
 #T:*.com:net_com.motd
 
-# A different MOTD for ourselves, where we point out that the helpdesk
-# better not be bothered with questions regarding irc...
-#T:*.london.ac.uk:london.motd
 
-#
-# In some ways similar to Undernet's ``Uworld'', HidoiNET provides channel
-# and operator services for many uses. At the time this config was written,
-# such services on HidoiNET currently include Operserv(O) and Ki.
-#
-# On HidoiNET, it is very important to keep these U: lines up to date and
-# changed as required. However generally, the need for change is very rare
-#
+# In some ways similar to Undernet's original ``Uworld'', QuakeNet and
+# B2IRC provide channel and operator services for many uses. 
+# In short words: something very important for network operations
+#
+# These lines must be the same on ALL servers on the network, or you will
+# get slapped with a long SCSI cable. This cannot be stressed enough - 
+# make SURE you have these right and kept up to date.
+#
+# The following lines are used on QuakeNet - please verify their current 
+# validity from other admins first, just to be sure
+#U:uworld2.quakenet.org:U2:*
+#U:uworld.quakenet.org:U:*
+#U:CServe.quakenet.org:Q:*
+#U:CServe2.quakenet.org:Q2:*
+#U:operserv.quakenet.org:O,Q3,Q4,UWorld,NickServ,ChanServ,telnet,backdoor,qauth,auth,admin,support,operserv:*
+#U:proxyscan.quakenet.org:P:*
+
+# The following are used on B2IRC - once again, better to be safe 
+# than sorry, so verify these before starting your server
+#U:o.services.b2irc.net:O,UWorld,NickServ,ChanServ,telnet,backdoor,admin:*
+#U:ki.services.b2irc.net:K:*
 
-U:o.services.hidoinet.org:O:* 
-U:ki.services.hidoinet.org:Ki:* 
 
-#
 # While running your server, you will most probably encounter individuals
 # or groups of persons that you do not wish to have access to your server.
-#
 # For this purpose, the ircd understands "kill lines".
-# K:<host/IP mask>:"<opt reason>":<username mask>
-#
-# It is possible to use a file as comment for the ban.
-# K:<host/IP mask>:!<path to file>:<usermask>
-#
+# K:<host/IP mask>:<opt reason>:<username mask>
+# If compiled with COMMENT_IS_FILE defined, it is possible to use a file
+# as comment for the ban.
+# K:<host/IP mask>:<path to file>:<usermask>
 # The default reason is: "You are banned from this server"
+#
 # Note that K: lines are local to the server; if you ban a person or a
 # whole domain from your server, they can get on IRC via any other server
-# that doesn't have them K: lined (yet).
-
-# With a simple comment, using quotes:
+# that doesn't have them K: lined . For this reason, QuakeNet and B2IRC 
+# use G: lines instead, which are activated through operator services.
+# G: lines can have an expiration date, can be easily added and removed, and
+# are always global. Some simple K: lines can be defined here though, 
+# which don't need to be modified
 #
-# Klines based on geographical location should not be enabled on HidoiNET
-# unless specifically required
-#K:*.au:"Please use a nearer server":*
-#K:*.edu:"Please use a nearer server":*
-
-# With a file, prepending a '!' before the filename.
-# The file can contain for example, a reason, a link to the
-# server rules and a contact address.
-#
-# Once again, these should not be used on HidoiNET in normal situations
-#K:unixbox.flooder.co.uk:!kline/youflooded.txt:*luser
-
-# Root users should not run IRC, for many obvious reasons. These
-# options should be used on all HidoiNET Servers 
-K:*:no_root_users:root
-K:*:no_root_users:~root
-
+# Yet again, the original u2.10.10 example.conf has more examples for these
+K:*:no_root_users:*root
 
-#
 # IP-based kill lines are designated with a lowercase 'k'.  These lines
 # use the same format as normal K: lines, except they apply to all hosts,
 # even if an IP address has a properly resolving host name.
-k:192.168.*:!klines/martians:*
+k:192.168.*:klines/martians:*
 
 
 # You probably want your server connected to other servers, so your users
@@ -305,143 +286,139 @@
 # server links is provided for ircd to decide what links to allow, what
 # to let humans do themselves, and what links to (forcefully) disallow.
 #
-# The Connection lines (also known as C lines)
+# The Connection and Allowing connection lines (also known as C/N lines)
 # define what servers the server connect to, and which servers are
-# allowed to connect.
+# allowed to connect. Note that they come in pairs; they do not work if
+# one if present and the other is absent.
 # C:<remote hostname or IP>:<password>:<remote server name>:<port>:<class>
 #
-# If the "port" field is omitted, the server will not attempt to
-# establish a link with that server ("not autoconnecting").
+# If the "port" field is omitted, the server will not attempt to 
+# automatically establish a link with that server ("not autoconnecting").
+#
+# For security reasons, real hub ip's for QuakeNet or B2IRC are not 
+# written here. When your server application is accepted, you will 
+# receive all neccessary information to connect
+#
+# Our primary uplink
+#C:11.33.55.77:linkpassword:hub.dk.quakenet.org:4400:90
+#
+# Our backup link
+#C:22.44.66.88:linkpassword:hub.uk.quakenet.org:4400:80
 
-# Our primary uplink.
-C:1.2.3.4:passwd:hub.fi.hidoinet.org:4400:90
 
-#
 # If your server starts on a bit larger network, you'll probably get
 # assigned one or two uplinks to which your server can connect.
 # If your uplink(s) also connect to other servers than yours (which is
 # probable), you need to define your uplink as being allowed to "hub".
 # H:<allowed hostmask>::<server name>
 #
-# Once again, on HidoiNET, keeping these up to date is very important
-H:*.*::hub.fi.hidoinet.org
+# Like U: lines, having these incorrectly defined will get you whacked with
+# long SCSI cables(Firewire cables reserved for future versions). Following
+# are current QuakeNet and B2IRC H: lines, but you should verify them before
+# starting your server, just to be safe.
+#
+# QuakeNet
+#H:*::hub.dk.quakenet.org
+#H:*::irc1.edome.quakenet.org
+#H:*::irc2.edome.quakenet.org
+#H:*::chalmers.se.quakenet.org
+#H:*::ircdev.quakenet.org
+#H:*::irc.uk.quakenet.org
+#H:*::chat.uk.quakenet.org
+#H:*::uworld.quakenet.org
+#H:*::uworld2.quakenet.org
+#H:*::hub.uk.quakenet.org
+#H:*::hub.de.quakenet.org
+#
+# B2IRC
+#H:*::irc.fi.b2irc.net
+#H:*::hub.fi.b2irc.net
+
 
-#
 # Of course, the opposite is also possible: forcing a server to be
 # a leaf. L: lines follow Murphy's Law: if you use them, there's a big
 # chance that routing will be screwed up afterwards.
 # L:<opt disallowed hostmask>::<server mask>:<opt max depth>
 
-#
+
 # For an advanced, real-time rule-based routing decision making system
 # you can use Disallow lines. For more information, see doc/readme.crules.
-#
-# Generally, on HidoiNET, you can ignore most of these.
-#
 # D:<server mask that ircd will refuse to connect to>::<rule>
 # d:<server mask that ircd will not autoconnect to>::<rule>
-# D:*.US.UnderNet.org::connected(*.US.UnderNet.org)
-# d:*.EU.UnderNet.org::connected(Amsterdam.NL.EU.*)
-
-# In some cases, this may be required on a HidoiNET server, but not generally
-# 
+#D:*.US.UnderNet.org::connected(*.US.UnderNet.org)
+#d:*.EU.UnderNet.org::connected(Amsterdam.NL.EU.*)
+#
 # The following line is recommended for leaf servers:
-# d:*::directcon(*)
+#d:*::directcon(*)
+
 
-#
 # Inevitably, you have reached the part about "IRC Operators". Oper status
 # grants some special privileges to a user, like the power to make the
-# server break or (try to) establish a connection with another server,
-# and to "kill" users off IRC.
+# server break or(try to) establish a connection with another server,
+# to "kill" users off IRC, and to use special network services.
+#
 # I can write many pages about this; I will restrict myself to saying that
 # if you want to appoint somebody as IRC Operator on your server, that
 # person should be aware of his/her responsibilities, and that you, being
 # the admin, will be held accountable for their actions.
 #
-# On HidoiNET, all operators are chosen with a global decisions, and local
-# IRCD admins may not add operators at their own will in any situation. Local
-# operators (o: lines) are not used at all on HidoiNET, all operators are
-# global, and such defined as O: lines.
-#
-# Avoid using the same password in many places, and try to avoid too global
-# netmasks. *@*.aol.com is generally a VERY bad idea, even with a difficult
-# password. Every server admin is responsible for keeping their O: lines
-# properly configured and out of reach from outsiders. Fixed ident lines
-# should generally be always used.
-#
-# If an operator is using a fakehost (F: line), the O: line must also be
-# defined for the fakehost, and not the actual FQDN.
-#
-# Use encrypted passwords whenever possible, especially when the ircd box
-# is not dedicated, and many users have access to the files.
-#
-# O:<host/IP mask>:<encrypted password>:<Nick>::<connection class>
-
-O:cooloper@*.coolopersdomain.net:VRKLKuGKn0jLs:cooloper::10
-
-# Note that the <connection class> is optional, but leaving it away
-# puts the O: lines in class 0, which usually only accepts one connection
-# at a time.  If you want users to Oper up more then once per O: line,
-# then use a connection class that allows more then one connection,
-# for example (using class 10 as in the example above):
-# Y:10:90:0:100:160000
+# Also worth noting is the generic Operator policy for both QuakeNet and 
+# B2IRC - server administrators MAY NOT add operators without the approval
+# of other operators. Adding O: lines on your own is a very quick and 
+# certain way to have your server delinked from the network permanently.
+#
+# Depending on options chose in make config, the password may be in plain 
+# text or encrypted. Before blaming anyone else, make sure you use the 
+# correct password types here. Naturally, having a plain text password 
+# in an O: line and defining crypted password will make the O: line useless
+#
+# O:<host/IP mask>:<password>:<Nick>::<opt connection class>
+#
+# An O: line with a cleartext password is defined as follows
+#O:vekotin@*.b2irc.net:mypassword:Vekotin::10
+#
+# Here's the same with a crypted password:
+#O:vekotin@*.b2irc.net:1z2Nci3OYg6AU:Vekotin::10
+
 
-# [P:lines]
 # When your server gets fuller, you will notice delays when trying to
 # connect to your server's primary listening port. Via the Port lines
-# it is possible to specify additional ports for ircd to listen to.
+# it is possible to specify additional ports (both AF_UNIX and AF_INET)
+# for ircd to listen to.
 # De facto ports are: 6667 - standard; 6660-6669 - additional client
-# ports;
-# Undernet uses 4400 for server listener ports.
+# ports; 7000 - original Undernet port; 4400, 7777 - used mainly for
+# server-to-server connections.
 # These are just hints, they are in no way official IANA or IETF policies.
 #
-# The interface setting allows multiply homed hosts to specify which
-# interface to use on a port by port basis, if an interface is not specified
-# the default interface will be used. The interface MUST be the complete
-# IP address for a real hardware interface on the machine running ircd.
-#
-# The [CS][H] field is an optional field to specify that a port is a
-# server port or a client port and whether it's hidden or not.
-# If used the first character MUST be either a C or S.
-# If you want to hide a port from /stats p from non-opers follow the C
-# or S with an H
-#
-# Unless you are using virtual hosts, the default settings should work
-# nicely on HidoiNET servers.
-#
-# P:<hostmask>:<interface>:<[CS][H]>:<client port number>
-#
+# On a side note, the /UPING command uses port 7007/udp. If your server
+# is located behind a firewall, you may want to make another hole in it
+# for this port.
+# P:<hostmask, or path>:::<port number>
+#
+# If you've defined virtual hosting during make config, you may want to
+# restrict incoming connections to a certain IP. Remember - the vhost for
+# outgoing connections is defined on the M: line
+
 # This is a normal server port, you need to have at least one server
 # port defined if you want to connect your server to other servers.
 P:::S:4400
 
 # This is a Server port that is Hidden. Something you probably won't need
-# at all on HidoiNET.
+# at all on QuakeNet or B2IRC.
 #P:::SH:4401
 
 # The following are normal client ports
 P:::C:6667
 P::::6668
 
+# Considering that you've reached this far without too many heart attacks,
+# probably means that you've either configured your ircd or just shamefully
+# skipped to the end of this file for some strange reason.
 #
-# Again something not generally used on HidoiNET
+# For information on linking to QuakeNet, please see the QuakeNet official 
+# website at http://www.quakenet.org/ as well as the application form at
+# http://www.quakenet.org/server_application
 #
-#P:*.nl:::6666
-
-# This is a hidden client port, listening on the interface associated
-# with the IP address 168.8.21.107
-# ...something you should not need on HidoiNET, except in special cases
-#P:*:168.8.21.107:CH:7000
-
-# You have reached the end of the HidoiNET example configuration. As mentioned
-# in many places above, it's better to be safe than sorry when configuring your
-# server. Other server admins will be happy to provide you with details in case
-# of uncertainties.
-#
-# The authors of this configuration file may be reached via <irc@hidoinet.org>
+# For information on linking to B2IRC, please visit http://www.b2irc.net/
 #
-# This example config is based on the original Undernet sample configuration fi
-le
-# and we wish to extend our thanks to it's original author(s).
-#
-
+# Good luck! -Vekotin
diff -u -r -N ircu2.10-lain-vanilla/include/client.h ircu2.10-lain/include/client.h
--- ircu2.10-lain-vanilla/include/client.h	Sun Apr 22 21:41:07 2001
+++ ircu2.10-lain/include/client.h	Sat Jun  2 05:39:14 2001
@@ -200,6 +200,7 @@
 #define FLAGS_DOID      0x00040000      /* I-lines say must use ident return */
 #define FLAGS_NONL      0x00080000      /* No \n in buffer */
 #define FLAGS_TS8       0x00100000      /* Why do you want to know? */
+#define FLAGS_HIDECHAN  0x00200000      /* Hides chans on operators */
 #define FLAGS_MAP       0x00800000      /* Show server on the map */
 #define FLAGS_JUNCTION  0x01000000      /* Junction causing the net.burst */
 #define FLAGS_DEAF      0x02000000      /* Makes user deaf */
@@ -212,7 +213,7 @@
 #define FLAGS_XTRAOP    0x80000000	/* Special oper powers */
 
 #define SEND_UMODES \
-    (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_DEAF|FLAGS_CHSERV|FLAGS_DEBUG|FLAGS_XTRAOP)
+    (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_DEAF|FLAGS_CHSERV|FLAGS_DEBUG|FLAGS_XTRAOP|FLAGS_HIDECHAN)
 #define ALL_UMODES (SEND_UMODES|FLAGS_SERVNOTICE|FLAGS_LOCOP)
 #define FLAGS_ID (FLAGS_DOID|FLAGS_GOTID)
 
@@ -236,6 +237,7 @@
 #define IsLocOp(x)              ((x)->flags & FLAGS_LOCOP)
 #define IsLocal(x)              ((x)->flags & FLAGS_LOCAL)
 #define IsOper(x)               ((x)->flags & FLAGS_OPER)
+#define IsHidechan(x)           ((x)->flags & FLAGS_HIDECHAN)
 #define IsUPing(x)              ((x)->flags & FLAGS_UPING)
 #define NoNewLine(x)            ((x)->flags & FLAGS_NONL)
 #define SendDebug(x)            ((x)->flags & FLAGS_DEBUG)
@@ -257,6 +259,7 @@
 #define SetJunction(x)          ((x)->flags |= FLAGS_JUNCTION)
 #define SetLocOp(x)             ((x)->flags |= FLAGS_LOCOP)
 #define SetOper(x)              ((x)->flags |= FLAGS_OPER)
+#define SetHidechan(x)          ((x)->flags |= FLAGS_HIDECHAN)
 #define SetUPing(x)             ((x)->flags |= FLAGS_UPING)
 #define SetWallops(x)           ((x)->flags |= FLAGS_WALLOP)
 
@@ -271,6 +274,7 @@
 #define ClearInvisible(x)       ((x)->flags &= ~FLAGS_INVISIBLE)
 #define ClearLocOp(x)           ((x)->flags &= ~FLAGS_LOCOP)
 #define ClearOper(x)            ((x)->flags &= ~FLAGS_OPER)
+#define ClearHidechan(x)        ((x)->flags &= ~FLAGS_HIDECHAN)
 #define ClearUPing(x)           ((x)->flags &= ~FLAGS_UPING)
 #define ClearWallops(x)         ((x)->flags &= ~FLAGS_WALLOP)
 
@@ -302,9 +306,9 @@
 
 #define SNO_USER        (SNO_ALL & ~SNO_OPER)
 
-#define SNO_DEFAULT (SNO_NETWORK|SNO_OPERKILL|SNO_GLINE)
-#define SNO_OPERDEFAULT (SNO_DEFAULT|SNO_HACK2|SNO_HACK4|SNO_THROTTLE|SNO_OLDSNO)
-#define SNO_OPER (SNO_CONNEXIT|SNO_OLDREALOP)
+#define SNO_DEFAULT (SNO_NETWORK|SNO_OPERKILL)
+#define SNO_OPERDEFAULT (SNO_DEFAULT|SNO_HACK2|SNO_GLINE|SNO_THROTTLE|SNO_OLDSNO)
+#define SNO_OPER (SNO_CONNEXIT|SNO_OLDREALOP|SNO_HACK2|SNO_HACK3|SNO_UNAUTH|SNO_TCPCOMMON|SNO_TOOMANY|SNO_HACK4|SNO_GLINE|SNO_IPMISMATCH|SNO_THROTTLE)
 #define SNO_NOISY (SNO_SERVKILL|SNO_UNAUTH)
 
 typedef enum ShowIPType {
diff -u -r -N ircu2.10-lain-vanilla/include/gline.h ircu2.10-lain/include/gline.h
--- ircu2.10-lain-vanilla/include/gline.h	Sat Mar 18 07:20:28 2000
+++ ircu2.10-lain/include/gline.h	Sat Jun  2 05:14:00 2001
@@ -55,6 +55,7 @@
   char*          host;
   char*          reason;
   char*          name;
+  char*          nick;
   time_t         expire;
   unsigned int   gflags;
 };
@@ -65,12 +66,14 @@
 extern void gline_remove_expired(time_t now);
 
 extern void add_gline(struct Client *sptr, int ip_mask,
-                      char *host, char *comment, char *user,
+                      char *host, char *comment, char *user, char *nick,
                       time_t expire, int local);
 extern struct Gline* make_gline(int is_ipmask, char *host, char *reason,
-                                char *name, time_t expire);
+                                char *name, char *nick, time_t expire);
 extern struct Gline* find_gline(struct Client *cptr, struct Gline **pgline);
 extern void free_gline(struct Gline *gline, struct Gline *prev);
+
+extern int IsGlinedNick(struct Client *cptr, char *nick);
 
 #ifdef BADCHAN
 extern int bad_channel(const char* name);
diff -u -r -N ircu2.10-lain-vanilla/include/patchlevel.h ircu2.10-lain/include/patchlevel.h
--- ircu2.10-lain-vanilla/include/patchlevel.h	Thu May 24 23:12:32 2001
+++ ircu2.10-lain/include/patchlevel.h	Sun Jun  3 02:33:00 2001
@@ -19,9 +19,9 @@
  *
  */
 
-#define PATCHLEVEL "+lain(1.1.1)"
+#define PATCHLEVEL "lain(1.1.2)"
 
-#define RELEASE ".10"
+#define RELEASE ".10+"
 
 /*
  * Deliberate empty lines
diff -u -r -N ircu2.10-lain-vanilla/ircd/IPcheck.c ircu2.10-lain/ircd/IPcheck.c
--- ircu2.10-lain-vanilla/ircd/IPcheck.c	Mon Apr  9 09:12:03 2001
+++ ircu2.10-lain/ircd/IPcheck.c	Sun Jun  3 02:38:29 2001
@@ -63,7 +63,7 @@
 #define CONNECTED_SINCE(x) (NOW - (x))
 
 #define IPCHECK_CLONE_LIMIT 4
-#define IPCHECK_CLONE_PERIOD 40
+#define IPCHECK_CLONE_PERIOD 20
 #define IPCHECK_CLONE_DELAY 600
 
 
diff -u -r -N ircu2.10-lain-vanilla/ircd/gline.c ircu2.10-lain/ircd/gline.c
--- ircu2.10-lain-vanilla/ircd/gline.c	Thu May 24 23:35:03 2001
+++ ircu2.10-lain/ircd/gline.c	Sat Jun  2 08:31:45 2001
@@ -23,8 +23,12 @@
 #include "client.h"
 #include "ircd.h"
 #include "ircd_alloc.h"
+#include "hash.h"
+#include "channel.h"
 #include "ircd_string.h"
 #include "match.h"
+#include "numnicks.h"
+#include "msg.h"
 #include "numeric.h"
 #include "s_bsd.h"
 #include "s_misc.h"
@@ -39,7 +43,7 @@
 
 
 struct Gline *make_gline(int is_ipmask, char *host, char *reason,
-                         char *name, time_t expire)
+                         char *name, char *nick, time_t expire)
 {
   struct Gline *agline;
 
@@ -54,6 +58,7 @@
   DupString(agline->host, host);        /* copy vital information */
   DupString(agline->reason, reason);
   DupString(agline->name, name);
+  DupString(agline->nick, nick);
   agline->expire = expire;
   agline->gflags = GLINE_ACTIVE;        /* gline is active */
   if (is_ipmask)
@@ -94,7 +99,8 @@
     if ((GlineIsIpMask(gline) ?
         match(gline->host, ircd_ntoa((const char*) &cptr->ip)) :
         match(gline->host, cptr->sockhost)) == 0 &&
-        match(gline->name, cptr->user->username) == 0) {
+        match(gline->name, cptr->user->username) == 0 &&
+        (cptr->name && match(gline->nick, cptr->name)==0)) {
       if (pgline)
         *pgline = prev; /* If they need it, give them the previous gline
                                    entry (probably for free_gline, below) */
@@ -108,6 +114,43 @@
   return 0;                  /* found no glines */
 }
 
+int IsGlinedNick(struct Client *cptr, char *nick)
+{
+  struct Gline* gline = GlobalGlineList;
+  struct Gline* prev = 0;
+
+  while (gline) {
+    /*
+     * look through all glines
+     */
+    if (gline->expire <= TStime()) {
+      /*
+       * handle expired glines
+       */
+      free_gline(gline, prev);
+      gline = prev ? prev->next : GlobalGlineList;
+      if (!gline)
+        break;                  /* gline == NULL means gline == NULL */
+      continue;
+    }
+
+    /* Does gline match? */
+    /* Added a check against the user's IP address as well -Kev */
+    if ((GlineIsIpMask(gline) ?
+        match(gline->host, ircd_ntoa((const char*) &cptr->ip)) :
+        match(gline->host, cptr->sockhost)) == 0 &&
+        match(gline->name, cptr->user->username) == 0 &&
+        (cptr->name && match(gline->nick, nick)==0)) {
+      return 1;
+    }
+
+    prev = gline;
+    gline = gline->next;
+  }
+
+  return 0;                  /* found no glines */
+}
+
 void free_gline(struct Gline* gline, struct Gline* prev)
 {
   assert(0 != gline);
@@ -129,6 +172,7 @@
   MyFree(gline->host);  /* and free up the memory */
   MyFree(gline->reason);
   MyFree(gline->name);
+  MyFree(gline->nick);
   MyFree(gline);
 }
 
@@ -186,7 +230,7 @@
 
 
 void add_gline(struct Client *sptr, int ip_mask, char *host, char *comment,
-               char *user, time_t expire, int local)
+               char *user, char *nick, time_t expire, int local)
 {
   struct Client *acptr;
   struct Gline *agline;
@@ -201,15 +245,15 @@
 
   /* Inform ops */
   sendto_op_mask(SNO_GLINE,
-      "%s%s[+] for %s@%s, from %s, expires " TIME_T_FMT ", reason: %s",
+      "%s%s[+] for %s!%s@%s, from %s, expires " TIME_T_FMT ", reason: %s",
       local ? "LOCAL ":"", gtype ? "BADCHAN" : "GLINE",
-      user, host, sptr->name, expire, comment);
+      nick, user, host, sptr->name, expire, comment);
 
 #ifdef GPATH
   write_log(GPATH,
-      "# " TIME_T_FMT " %s adding %s %s for %s@%s, expiring at " TIME_T_FMT
+      "# " TIME_T_FMT " %s adding %s %s for %s!%s@%s, expiring at " TIME_T_FMT
       ": %s\n", TStime(), sptr->name, local ? "local" : "global",
-      gtype ? "BADCHAN" : "GLINE", user, host, expire, comment);
+      gtype ? "BADCHAN" : "GLINE", nick, user, host, expire, comment);
 
   /* this can be inserted into the conf */
   if (!gtype)
@@ -217,13 +261,42 @@
       user);
 #endif /* GPATH */
 
-  agline = make_gline(ip_mask, host, comment, user, expire);
+  agline = make_gline(ip_mask, host, comment, user, nick, expire);
   if (local)
     SetGlineIsLocal(agline);
 
 #ifdef BADCHAN
+/*
+ * If this is badchannel g-line, let's kick our users from the channel
+ */
   if (gtype)
+  {
+    struct Channel* chptr;
+    struct Channel* chptr_next=0;
+    struct Membership* member;
+    struct Membership* member_next=0;
+  
+    for(chptr = GlobalChannelList; chptr; chptr = chptr_next)
+    {
+      chptr_next = chptr->next;
+      if(match(agline->host, chptr->chname))
+        continue;
+      for(member = chptr->members; member; member=member_next)
+      {
+        member_next = member->next_member;
+        if(!(member->user) || !MyUser(member->user))
+          continue;
+        if(IsZombie(member))
+          continue;
+        sendto_highprot_butone(0, 10, "%s " TOK_KICK " %s %s%s :Badchanneled",
+            NumServ(&me), chptr->chname, NumNick(member->user));
+        sendto_channel_butserv(chptr, &me, ":%s KICK %s %s :Badchanneled", 
+           me.name, chptr->chname, member->user->name);
+        make_zombie(member, member->user, &me, &me, chptr);
+      }
+    }
     return;
+  }
 #endif
 
   for (fd = HighestFd; fd >= 0; --fd) { 
@@ -243,10 +316,22 @@
                                    find_kill for safety's sake */
 #endif
 
-      if ((GlineIsIpMask(agline) ?  match(agline->host, acptr->sock_ip) :
-          match(agline->host, acptr->sockhost)) == 0 &&
+/*
+      if (((GlineIsIpMask(agline) ?  match(agline->host, acptr->sock_ip) :
+          (match(agline->host, acptr->sockhost)) == 0 || 
+          (IsSetHost(acptr) && match(agline->host, acptr->user->orighost)==0))) &&
           (!acptr->user->username ||
-          match(agline->name, acptr->user->username) == 0))
+          (match(agline->name, acptr->user->username) == 0 ||
+          (IsSetHost(acptr) && match(agline->name, acptr->user->origuser)==0))) &&
+          (!acptr->name || match(agline->nick, acptr->name)==0))
+*/
+      if(
+        ((GlineIsIpMask(agline)?match(agline->host, acptr->sock_ip):match(agline->host, acptr->sockhost)) == 0 ||
+        (IsSetHost(acptr) && match(agline->host, acptr->user->orighost)==0)) &&
+        (!acptr->user->username || match(agline->name, acptr->user->username) == 0 ||
+        (IsSetHost(acptr) && match(agline->name, acptr->user->origuser)==0)) &&
+        (!acptr->name || match(agline->nick, acptr->name) == 0)
+        )
       {
 
         /* ok, he was the one that got G-lined */
@@ -264,4 +349,3 @@
     }
   }
 }
-
diff -u -r -N ircu2.10-lain-vanilla/ircd/ircd_relay.c ircu2.10-lain/ircd/ircd_relay.c
--- ircu2.10-lain-vanilla/ircd/ircd_relay.c	Sat Mar 18 07:20:28 2000
+++ ircu2.10-lain/ircd/ircd_relay.c	Thu May 31 23:14:39 2001
@@ -303,7 +303,7 @@
    */
   if (0 == (acptr = findNUser(name)) || !IsUser(acptr)) {
     sendto_one(sptr,
-               ":%s %d %s * :Target left UnderNet. Failed to deliver: [%.20s]",
+               ":%s %d %s * :Target left " NETWORKNAME ". Failed to deliver: [%.20s]",
                me.name, ERR_NOSUCHNICK, sptr->name, text);
     return;
   }
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_gline.c ircu2.10-lain/ircd/m_gline.c
--- ircu2.10-lain-vanilla/ircd/m_gline.c	Thu May 24 23:37:34 2001
+++ ircu2.10-lain/ircd/m_gline.c	Sat Jun  2 05:06:14 2001
@@ -130,8 +130,10 @@
   struct Client* acptr = 0;  /* Init. to avoid compiler warning. */
   struct Gline*  gline;
   struct Gline*  prev;
+  char*          nick;
   char*          user;
   char*          host;
+  char*          tmp;
   int            active;
   int            ip_mask;
   int            gtype = 0;
@@ -200,6 +202,7 @@
                                    should add this gline */
       }
 
+#if 0
       if (!(host = strchr(parv[2], '@'))) {
         /*
          * convert user@host no @'s; assume username is '*'
@@ -211,6 +214,36 @@
         user = parv[2];
         *(host++) = '\0';       /* break up string at the '@' */
       }
+#endif
+/* 
+ * We can now expect G-lines to be in following formats
+ *    "host", "user@host", "nick!user@host"
+ * and we have to check all these combinations
+ *   ++Bafi
+ */
+      if(!(host = strchr(parv[2], '@'))) {
+         /* No @ in argument.. so this is case "host" */
+         user = "*";
+         nick = "*";
+         host = parv[2];
+       }
+       else
+       {
+         tmp = parv[2];
+         *(host++) = '\0';
+         if(!(user = strchr(tmp, '!')))
+         {
+           /* Case 'user@host' */
+           user = tmp;
+           nick = "*";
+         }
+         else
+         {
+           /* Case "nick!user@host" */
+           nick = tmp;
+           *(user++) = '\0';
+         }
+       }
       ip_mask = check_if_ipmask(host);  /* Store this boolean */
 #ifdef BADCHAN
       if ('#' == *host || '&' == *host || '+' == *host)
@@ -220,7 +253,8 @@
            gline = gline->next)
       {
         if (0 == ircd_strcmp(gline->name, user) &&
-            0 == ircd_strcmp(gline->host, host))
+            0 == ircd_strcmp(gline->host, host) &&
+            0 == ircd_strcmp(gline->nick, nick))
           break;
         prev = gline;
       }
@@ -230,12 +264,12 @@
         /*
          * removing the gline, notify opers
          */
-	sendto_op_mask(SNO_GLINE, "%s[-] for %s@%s by %s",
-            gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, parv[0]);
+	sendto_op_mask(SNO_GLINE, "%s[-] for %s!%s@%s by %s",
+            gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, parv[0]);
 
 #ifdef GPATH
-       write_log(GPATH, "# " TIME_T_FMT " %s removing %s for %s@%s\n",
-           TStime(), parv[0], gtype ? "BADCHAN" : "GLINE", gline->name, 
+       write_log(GPATH, "# " TIME_T_FMT " %s removing %s for %s!%s@%s\n",
+           TStime(), parv[0], gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, 
             gline->host);
 #endif /* GPATH */
 
@@ -248,13 +282,13 @@
         {                       /* new expire time? */
           /* yes, notify the opers */
           sendto_op_mask(SNO_GLINE,
-             "%s[r] for %s@%s to " TIME_T_FMT " by %s",
-             gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, expire, parv[0]);
+             "%s[r] for %s!%s@%s to " TIME_T_FMT " by %s",
+             gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, expire, parv[0]);
 #ifdef GPATH
           write_log(GPATH, "# " TIME_T_FMT " %s resetting expiration time "
-              "on %s for %s@%s to " TIME_T_FMT "\n",
+              "on %s for %s!%s@%s to " TIME_T_FMT "\n",
               TStime(), parv[0], gtype ? "BADCHAN" : "GLINE",
-              gline->name, gline->host, expire);
+              gline->nick, gline->name, gline->host, expire);
 #endif /* GPATH */
 
           gline->expire = expire;       /* reset the expire time */
@@ -262,13 +296,13 @@
         else if (!gline)
         {                       /* create gline */
           for (gline = (gtype) ? BadChanGlineList : GlobalGlineList; gline; gline = gline->next)
-            if (!mmatch(gline->name, user) &&
+            if (!mmatch(gline->nick, nick) && !mmatch(gline->name, user) &&
                 (ip_mask ? GlineIsIpMask(gline) : !GlineIsIpMask(gline)) &&
                 !mmatch(gline->host, host))
               return 0;         /* found an existing G-line that matches */
 
           /* add the line: */
-          add_gline(sptr, ip_mask, host, parv[4], user, expire, 0);
+          add_gline(sptr, ip_mask, host, parv[4], user, nick, expire, 0);
         }
       }
     }
@@ -278,7 +312,7 @@
     /* Not enough args and a user; list glines */
     for (gline = GlobalGlineList; gline; gline = gline->next)
       sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0],
-          gline->name, gline->host, gline->expire, gline->reason,
+          gline->nick, gline->name, gline->host, gline->expire, gline->reason,
           GlineIsActive(gline) ? (GlineIsLocal(gline) ? " (local)" : "") :
           " (Inactive)");
     sendto_one(cptr, rpl_str(RPL_ENDOFGLIST), me.name, parv[0]);
@@ -315,6 +349,7 @@
     else
       active = -1;
 
+#if 0
     if (!(host = strchr(parv[1], '@')))
     {
       user = "*";               /* no @'s; assume username is '*' */
@@ -325,6 +360,37 @@
       user = parv[1];
       *(host++) = '\0';         /* break up string at the '@' */
     }
+#endif
+/* 
+ * We can now expect G-lines to be in following formats
+ *    "host", "user@host", "nick!user@host"
+ * and we have to check all these combinations
+ *   ++Bafi
+ */
+      if(!(host = strchr(parv[2], '@'))) {
+         /* No @ in argument.. so this is case "host" */
+         user = "*";
+         nick = "*";
+         host = parv[2];
+       }
+       else
+       {
+         tmp = parv[2];
+         *(host++) = '\0';
+         if(!(user = strchr(tmp, '!')))
+         {
+           /* Case 'user@host' */
+           user = tmp;
+           nick = "*";
+         }
+         else
+         {
+           /* Case "nick!user@host" */
+           nick = tmp;
+           *(user++) = '\0';
+         }
+       }
+
     ip_mask = check_if_ipmask(host);    /* Store this boolean */
 #ifdef BADCHAN
     if ('#' == *host || '&' == *host || '+' == *host)
@@ -338,7 +404,7 @@
     for (gline = (gtype) ? BadChanGlineList : GlobalGlineList, prev = 0; gline;
          gline = gline->next)
     {
-      if (!mmatch(gline->name, user) &&
+      if (!mmatch(gline->nick, nick) && !mmatch(gline->name, user) &&
           (ip_mask ? GlineIsIpMask(gline) : !GlineIsIpMask(gline)) &&
           !mmatch(gline->host, host))
         break;
@@ -354,7 +420,7 @@
         if (parc < 4 || !strchr(parv[3], ' '))
           return need_more_params(sptr, "GLINE");
 
-        add_gline(sptr, ip_mask, host, parv[3], user, expire, 1);
+        add_gline(sptr, ip_mask, host, parv[3], user, nick, expire, 1);
       }
       else
 #endif
@@ -372,7 +438,7 @@
         expire == 0)
     {
       /* oper wants a list of one gline only */
-      sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0], gline->name,
+      sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0], gline->nick, gline->name,
           gline->host, gline->expire, gline->reason,
           GlineIsActive(gline) ? "" : " (Inactive)");
       sendto_one(cptr, rpl_str(RPL_ENDOFGLIST), me.name, parv[0]);
@@ -389,14 +455,14 @@
       {
         /* Remove local G-line */
           sendto_op_mask(SNO_GLINE,
-             "LOCAL %s[-] for %s@%s by %s",
-             gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, parv[0]);
+             "LOCAL %s[-] for %s!%s@%s by %s",
+             gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, parv[0]);
 #ifdef GPATH
         write_log(GPATH, "# " TIME_T_FMT
-            " %s!%s@%s removed local %s for %s@%s\n",
+            " %s!%s@%s removed local %s for %s!%s@%s\n",
             TStime(), parv[0], cptr->user->username, cptr->user->host,
             gtype ? "BADCHAN" : "GLINE",
-            gline->name, gline->host);
+            gline->nick, gline->name, gline->host);
 #endif /* GPATH */
         free_gline(gline, prev);        /* remove the gline */
         return 0;
@@ -414,17 +480,17 @@
     /* inform the operators what's up */
     if (active != -1)
     {                           /* changing the activation */
-       sendto_op_mask(SNO_GLINE, !expire ? "%s %sactivating %s for %s@%s" :
-          "%s %sactivating %s for %s@%s and "
+       sendto_op_mask(SNO_GLINE, !expire ? "%s %sactivating %s for %s!%s@%s" :
+          "%s %sactivating %s for %s!%s@%s and "
           "resetting expiration time to " TIME_T_FMT,
           parv[0], active ? "re" : "de", gtype ? "BADCHAN" : "GLINE",
-          gline->name, gline->host, gline->expire);
+          gline->nick, gline->name, gline->host, gline->expire);
 #ifdef GPATH
       write_log(GPATH, !expire ? "# " TIME_T_FMT " %s!%s@%s %sactivating "
-          "%s for %s@%s\n" : "# " TIME_T_FMT " %s!%s@%s %sactivating %s "
-          "for %s@%s and resetting expiration time to " TIME_T_FMT "\n",
+          "%s for %s!%s@%s\n" : "# " TIME_T_FMT " %s!%s@%s %sactivating %s "
+          "for %s!%s@%s and resetting expiration time to " TIME_T_FMT "\n",
           TStime(), parv[0], cptr->user->username, cptr->user->host,
-          active ? "re" : "de", gtype ? "BADCHAN" : "GLINE", gline->name, 
+          active ? "re" : "de", gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, 
           gline->host, gline->expire);
 #endif /* GPATH */
 
@@ -432,13 +498,13 @@
     else if (expire)
     {                           /* changing only the expiration */
           sendto_op_mask(SNO_GLINE,
-             "%s[r] for %s@%s to " TIME_T_FMT " by %s",
-             gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, expire, parv[0]);
+             "%s[r] for %s!%s@%s to " TIME_T_FMT " by %s",
+             gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, expire, parv[0]);
 #ifdef GPATH
       write_log(GPATH, "# " TIME_T_FMT " %s!%s@%s resetting expiration "
-          "time on %s for %s@%s to " TIME_T_FMT "\n", TStime(), parv[0],
+          "time on %s for %s!%s@%s to " TIME_T_FMT "\n", TStime(), parv[0],
           cptr->user->username, cptr->user->host, gtype ? "BADCHAN" : "GLINE",
-          gline->name, gline->host, gline->expire);
+          gline->nick, gline->name, gline->host, gline->expire);
 #endif /* GPATH */
     }
   }
@@ -471,6 +537,8 @@
   struct Gline*  prev;
   char*          user;
   char*          host;
+  char*          nick;
+  char*          tmp;
   int            active;
   int            ip_mask;
   int            gtype = 0;
@@ -539,6 +607,7 @@
                                    should add this gline */
       }
 
+#if 0
       if (!(host = strchr(parv[2], '@'))) {
         /*
          * convert user@host no @'s; assume username is '*'
@@ -550,6 +619,36 @@
         user = parv[2];
         *(host++) = '\0';       /* break up string at the '@' */
       }
+#endif
+/* 
+ * We can now expect G-lines to be in following formats
+ *    "host", "user@host", "nick!user@host"
+ * and we have to check all these combinations
+ *   ++Bafi
+ */
+      if(!(host = strchr(parv[2], '@'))) {
+         /* No @ in argument.. so this is case "host" */
+         user = "*";
+         nick = "*";
+         host = parv[2];
+       }
+       else
+       {
+         tmp = parv[2];
+         *(host++) = '\0';
+         if(!(user = strchr(tmp, '!')))
+         {
+           /* Case 'user@host' */
+           user = tmp;
+           nick = "*";
+         }
+         else
+         {
+           /* Case "nick!user@host" */
+           nick = tmp;
+           *(user++) = '\0';
+        }
+      }
       ip_mask = check_if_ipmask(host);  /* Store this boolean */
 #ifdef BADCHAN
       if ('#' == *host || '&' == *host || '+' == *host)
@@ -559,7 +658,8 @@
            gline = gline->next)
       {
         if (0 == ircd_strcmp(gline->name, user) &&
-            0 == ircd_strcmp(gline->host, host))
+            0 == ircd_strcmp(gline->host, host) &&
+            0 == ircd_strcmp(gline->nick, nick))
           break;
         prev = gline;
       }
@@ -569,12 +669,12 @@
         /*
          * removing the gline, notify opers
          */
-	sendto_op_mask(SNO_GLINE, "%s[-] for %s@%s by %s",
-            gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, parv[0]);
+	sendto_op_mask(SNO_GLINE, "%s[-] for %s!%s@%s by %s",
+            gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, parv[0]);
 
 #ifdef GPATH
-       write_log(GPATH, "# " TIME_T_FMT " %s removing %s for %s@%s\n",
-           TStime(), parv[0], gtype ? "BADCHAN" : "GLINE", gline->name, 
+       write_log(GPATH, "# " TIME_T_FMT " %s removing %s for %s!%s@%s\n",
+           TStime(), parv[0], gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, 
             gline->host);
 #endif /* GPATH */
 
@@ -587,14 +687,14 @@
         {                       /* new expire time? */
           /* yes, notify the opers */
           sendto_op_mask(SNO_GLINE,
-             "%s[r] for %s@%s to " TIME_T_FMT " by %s",
-             gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, expire, parv[0]);
+             "%s[r] for %s!%s@%s to " TIME_T_FMT " by %s",
+             gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, expire, parv[0]);
 
 #ifdef GPATH
           write_log(GPATH, "# " TIME_T_FMT " %s resetting expiration time "
-              "on %s for %s@%s to " TIME_T_FMT "\n",
+              "on %s for %s!%s@%s to " TIME_T_FMT "\n",
               TStime(), parv[0], gtype ? "BADCHAN" : "GLINE",
-              gline->name, gline->host, expire);
+              gline->nick, gline->name, gline->host, expire);
 #endif /* GPATH */
 
           gline->expire = expire;       /* reset the expire time */
@@ -602,13 +702,13 @@
         else if (!gline)
         {                       /* create gline */
           for (gline = (gtype) ? BadChanGlineList : GlobalGlineList; gline; gline = gline->next)
-            if (!mmatch(gline->name, user) &&
+            if (!mmatch(gline->nick, nick) && !mmatch(gline->name, user) &&
                 (ip_mask ? GlineIsIpMask(gline) : !GlineIsIpMask(gline)) &&
                 !mmatch(gline->host, host))
               return 0;         /* found an existing G-line that matches */
 
           /* add the line: */
-          add_gline(sptr, ip_mask, host, parv[4], user, expire, 0);
+          add_gline(sptr, ip_mask, host, parv[4], user, nick, expire, 0);
         }
       }
     }
@@ -618,7 +718,7 @@
     /* Not enough args and a user; list glines */
     for (gline = GlobalGlineList; gline; gline = gline->next)
       sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0],
-          gline->name, gline->host, gline->expire, gline->reason,
+          gline->nick, gline->name, gline->host, gline->expire, gline->reason,
           GlineIsActive(gline) ? (GlineIsLocal(gline) ? " (local)" : "") :
           " (Inactive)");
     sendto_one(cptr, rpl_str(RPL_ENDOFGLIST), me.name, parv[0]);
@@ -654,7 +754,7 @@
     }
     else
       active = -1;
-
+#if 0
     if (!(host = strchr(parv[1], '@')))
     {
       user = "*";               /* no @'s; assume username is '*' */
@@ -665,6 +765,36 @@
       user = parv[1];
       *(host++) = '\0';         /* break up string at the '@' */
     }
+#endif
+/* 
+ * We can now expect G-lines to be in following formats
+ *    "host", "user@host", "nick!user@host"
+ * and we have to check all these combinations
+ *   ++Bafi
+ */
+      if(!(host = strchr(parv[2], '@'))) {
+         /* No @ in argument.. so this is case "host" */
+         user = "*";
+         nick = "*";
+         host = parv[2];
+       }
+       else
+       {
+         tmp = parv[2];
+         *(host++) = '\0';
+         if(!(user = strchr(tmp, '!')))
+         {
+           /* Case 'user@host' */
+           user = tmp;
+           nick = "*";
+         }
+         else
+         {
+           /* Case "nick!user@host" */
+           nick = tmp;
+           *(user++) = '\0';
+         }
+       }
     ip_mask = check_if_ipmask(host);    /* Store this boolean */
 #ifdef BADCHAN
     if ('#' == *host || '&' == *host || '+' == *host)
@@ -678,7 +808,7 @@
     for (gline = (gtype) ? BadChanGlineList : GlobalGlineList, prev = 0; gline;
          gline = gline->next)
     {
-      if (!mmatch(gline->name, user) &&
+      if (!mmatch(gline->nick, nick) && !mmatch(gline->name, user) &&
           (ip_mask ? GlineIsIpMask(gline) : !GlineIsIpMask(gline)) &&
           !mmatch(gline->host, host))
         break;
@@ -694,7 +824,7 @@
         if (parc < 4 || !strchr(parv[3], ' '))
           return need_more_params(sptr, "GLINE");
 
-        add_gline(sptr, ip_mask, host, parv[3], user, expire, 1);
+        add_gline(sptr, ip_mask, host, parv[3], user, nick, expire, 1);
       }
       else
 #endif
@@ -712,7 +842,7 @@
         expire == 0)
     {
       /* oper wants a list of one gline only */
-      sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0], gline->name,
+      sendto_one(cptr, rpl_str(RPL_GLIST), me.name, parv[0], gline->nick, gline->name,
           gline->host, gline->expire, gline->reason,
           GlineIsActive(gline) ? "" : " (Inactive)");
       sendto_one(cptr, rpl_str(RPL_ENDOFGLIST), me.name, parv[0]);
@@ -728,14 +858,14 @@
       else if (GlineIsLocal(gline))
       {
         /* Remove local G-line */
-        sendto_op_mask(SNO_GLINE, "%s removed local %s for %s@%s",
-            parv[0], gtype ? "BADCHAN" : "GLINE", gline->name, gline->host);
+        sendto_op_mask(SNO_GLINE, "%s removed local %s for %s!%s@%s",
+            parv[0], gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host);
 #ifdef GPATH
         write_log(GPATH, "# " TIME_T_FMT
-            " %s!%s@%s removed local %s for %s@%s\n",
+            " %s!%s@%s removed local %s for %s!%s@%s\n",
             TStime(), parv[0], cptr->user->username, cptr->user->host,
             gtype ? "BADCHAN" : "GLINE",
-            gline->name, gline->host);
+            gline->nick, gline->name, gline->host);
 #endif /* GPATH */
         free_gline(gline, prev);        /* remove the gline */
         return 0;
@@ -753,32 +883,32 @@
     /* inform the operators what's up */
     if (active != -1)
     {                           /* changing the activation */
-       sendto_op_mask(SNO_GLINE, !expire ? "%s %sactivating %s for %s@%s" :
-          "%s %sactivating %s for %s@%s and "
+       sendto_op_mask(SNO_GLINE, !expire ? "%s %sactivating %s for %s!%s@%s" :
+          "%s %sactivating %s for %s!%s@%s and "
           "resetting expiration time to " TIME_T_FMT,
           parv[0], active ? "re" : "de", gtype ? "BADCHAN" : "GLINE",
-          gline->name, gline->host, gline->expire);
+          gline->nick, gline->name, gline->host, gline->expire);
 #ifdef GPATH
       write_log(GPATH, !expire ? "# " TIME_T_FMT " %s!%s@%s %sactivating "
-          "%s for %s@%s\n" : "# " TIME_T_FMT " %s!%s@%s %sactivating %s "
-          "for %s@%s and resetting expiration time to " TIME_T_FMT "\n",
+          "%s for %s!%s@%s\n" : "# " TIME_T_FMT " %s!%s@%s %sactivating %s "
+          "for %s!%s@%s and resetting expiration time to " TIME_T_FMT "\n",
           TStime(), parv[0], cptr->user->username, cptr->user->host,
           active ? "re" : "de", gtype ? "BADCHAN" : "GLINE", gline->name, 
-          gline->host, gline->expire);
+          gline->nick, gline->host, gline->expire);
 #endif /* GPATH */
 
     }
     else if (expire)
     {                           /* changing only the expiration */
           sendto_op_mask(SNO_GLINE,
-             "%s[r] for %s@%s to " TIME_T_FMT " by %s",
-             gtype ? "BADCHAN" : "GLINE", gline->name, gline->host, expire, parv[0]);
+             "%s[r] for %s!%s@%s to " TIME_T_FMT " by %s",
+             gtype ? "BADCHAN" : "GLINE", gline->nick, gline->name, gline->host, expire, parv[0]);
 
 #ifdef GPATH
       write_log(GPATH, "# " TIME_T_FMT " %s!%s@%s resetting expiration "
-          "time on %s for %s@%s to " TIME_T_FMT "\n", TStime(), parv[0],
+          "time on %s for %s!%s@%s to " TIME_T_FMT "\n", TStime(), parv[0],
           cptr->user->username, cptr->user->host, gtype ? "BADCHAN" : "GLINE",
-          gline->name, gline->host, gline->expire);
+          gline->nick, gline->name, gline->host, gline->expire);
 #endif /* GPATH */
     }
   }
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_nick.c ircu2.10-lain/ircd/m_nick.c
--- ircu2.10-lain-vanilla/ircd/m_nick.c	Sun May 20 18:30:18 2001
+++ ircu2.10-lain/ircd/m_nick.c	Sun Jun  3 02:18:35 2001
@@ -166,6 +166,15 @@
     return 0;
   }
 
+  /*
+   * Let's see if there is G-line active for that nick..
+   * - No need to check when registering.. they get caught later anyway..
+   */
+  if(IsRegistered(sptr) && !IsAnOper(sptr) && IsGlinedNick(sptr, nick))
+  {
+    sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, client_name, nick);
+    return 0;
+  }
   /* 
    * Check if this is a LOCAL user trying to use a reserved (Juped)
    * nick, if so tell him that it's a nick in use...
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_notice.c ircu2.10-lain/ircd/m_notice.c
--- ircu2.10-lain-vanilla/ircd/m_notice.c	Sat Mar 18 07:20:29 2000
+++ ircu2.10-lain/ircd/m_notice.c	Thu May 31 23:14:49 2001
@@ -349,7 +349,7 @@
         sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick);
       else
         sendto_one(sptr,
-            ":%s %d %s * :Target left UnderNet. Failed to deliver: [%.50s]",
+            ":%s %d %s * :Target left " NETWORKNAME ". Failed to deliver: [%.50s]",
             me.name, ERR_NOSUCHNICK, sptr->name, parv[parc - 1]);
       continue;
     }
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_privmsg.c ircu2.10-lain/ircd/m_privmsg.c
--- ircu2.10-lain-vanilla/ircd/m_privmsg.c	Sat Mar 18 07:20:29 2000
+++ ircu2.10-lain/ircd/m_privmsg.c	Thu May 31 23:14:59 2001
@@ -347,7 +347,7 @@
         sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick);
       else
         sendto_one(sptr,
-            ":%s %d %s * :Target left UnderNet. Failed to deliver: [%.50s]",
+            ":%s %d %s * :Target left " NETWORKNAME ". Failed to deliver: [%.50s]",
             me.name, ERR_NOSUCHNICK, sptr->name, parv[parc - 1]);
       continue;
     }
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_stats.c ircu2.10-lain/ircd/m_stats.c
--- ircu2.10-lain-vanilla/ircd/m_stats.c	Tue May 22 23:11:57 2001
+++ ircu2.10-lain/ircd/m_stats.c	Sat Jun  2 04:12:32 2001
@@ -295,7 +295,7 @@
       {
         for (gline = GlobalGlineList; gline; gline = gline->next) {
           sendto_one(sptr, rpl_str(RPL_STATSGLINE), me.name,
-                     sptr->name, 'G', gline->name, gline->host,
+                     sptr->name, 'G', gline->nick, gline->name, gline->host,
                      gline->expire, gline->reason);
         }
       }
@@ -719,7 +719,7 @@
       {
         for (gline = GlobalGlineList; gline; gline = gline->next) {
           sendto_one(sptr, rpl_str(RPL_STATSGLINE), me.name,
-                     sptr->name, 'G', gline->name, gline->host,
+                     sptr->name, 'G', gline->nick, gline->name, gline->host,
                     gline->expire, gline->reason);
         } 
       }
@@ -1143,7 +1143,7 @@
       {
         for (gline = GlobalGlineList; gline; gline = gline->next) {
           sendto_one(sptr, rpl_str(RPL_STATSGLINE), me.name,
-                     sptr->name, 'G', gline->name, gline->host,
+                     sptr->name, 'G', gline->nick, gline->name, gline->host,
                     gline->expire, gline->reason);
         } 
       }
@@ -1569,7 +1569,7 @@
       {
         for (gline = GlobalGlineList; gline; gline = gline->next) {
           sendto_one(sptr, rpl_str(RPL_STATSGLINE), me.name,
-                     sptr->name, 'G', gline->name, gline->host,
+                     sptr->name, 'G', gline->nick, gline->name, gline->host,
                      gline->expire, gline->reason);
         }
       }
diff -u -r -N ircu2.10-lain-vanilla/ircd/m_whois.c ircu2.10-lain/ircd/m_whois.c
--- ircu2.10-lain-vanilla/ircd/m_whois.c	Fri May 18 18:31:08 2001
+++ ircu2.10-lain/ircd/m_whois.c	Tue May 29 05:02:36 2001
@@ -231,7 +231,7 @@
         found = 1;
 
 exact_match:
-        if (user && !IsChannelService(acptr))
+        if (user && !IsChannelService(acptr) && !IsHidechan(acptr))
         {
           struct Membership* chan;
           mlen = strlen(me.name) + strlen(parv[0]) + 12 + strlen(name);
@@ -445,7 +445,7 @@
         found = 1;
 
 exact_match:
-        if (user && !IsChannelService(acptr))
+        if (user && !IsChannelService(acptr) && !IsHidechan(acptr))
         {
           struct Membership* chan;
           mlen = strlen(me.name) + strlen(parv[0]) + 12 + strlen(name);
@@ -659,7 +659,7 @@
         found = 1;
 
 exact_match:
-        if (user && !IsChannelService(acptr))
+        if (user && !IsChannelService(acptr) && !IsHidechan(acptr))
         {
           struct Membership* chan;
           mlen = strlen(me.name) + strlen(parv[0]) + 12 + strlen(name);
@@ -877,7 +877,7 @@
         found = 1;
 
 exact_match:
-        if (user && !IsChannelService(acptr))
+        if (user && !IsChannelService(acptr) && !IsHidechan(acptr))
         {
           struct Membership* chan;
           mlen = strlen(me.name) + strlen(parv[0]) + 12 + strlen(name);
diff -u -r -N ircu2.10-lain-vanilla/ircd/p_sethost.c ircu2.10-lain/ircd/p_sethost.c
--- ircu2.10-lain-vanilla/ircd/p_sethost.c	Thu May 17 23:56:31 2001
+++ ircu2.10-lain/ircd/p_sethost.c	Sat Jun  2 23:52:02 2001
@@ -345,9 +345,16 @@
   }  
   
   /* WALLOP's change of host (if applic.) */
-  if (LogOption(OPER_DYNHOST) && MyUser(sptr))
-     LogFeature(sptr, OPER_DYNHOST, "changed his/her host to '%s@%s'", newuser, newhost);    
-    
+  if(IsAnOper(sptr))
+  {
+    if (LogOption(OPER_DYNHOST) && MyUser(sptr))
+       LogFeature(sptr, OPER_DYNHOST, "changed his/her host to '%s@%s'", newuser, newhost);    
+  }
+  else
+  {
+    if (LogOption(USER_SETHOST) && MyUser(sptr))
+       LogFeature(sptr, USER_SETHOST, "activated user sethost for '%s@%s'", newuser, newhost);    
+  }
   /* Backup the user's host (for undoing purposes) */
   if (restore == 0 && !IsSetHost(sptr))
   {
diff -u -r -N ircu2.10-lain-vanilla/ircd/s_err.c ircu2.10-lain/ircd/s_err.c
--- ircu2.10-lain-vanilla/ircd/s_err.c	Sun Apr 22 22:47:42 2001
+++ ircu2.10-lain/ircd/s_err.c	Sat Jun  2 05:05:47 2001
@@ -613,7 +613,7 @@
 /* 246 */
   { RPL_STATSTLINE, "%c %s %s", "246" },
 /* 247 */
-  { RPL_STATSGLINE, "%c %s@%s " TIME_T_FMT " :%s", "247" },
+  { RPL_STATSGLINE, "%c %s!%s@%s " TIME_T_FMT " :%s", "247" },
 /* 248 */
   { RPL_STATSULINE, "%c %s %s %s %d %d", "248" },
 /* 249 */
@@ -679,7 +679,7 @@
 /* 279 */
   { 0 },
 /* 280 */
-  { RPL_GLIST, "%s@%s " TIME_T_FMT " %s%s", "280" },
+  { RPL_GLIST, "%s!%s@%s " TIME_T_FMT " %s%s", "280" },
 /* 281 */
   { RPL_ENDOFGLIST, ":End of G-line List", "281" },
 /* 282 */
diff -u -r -N ircu2.10-lain-vanilla/ircd/s_user.c ircu2.10-lain/ircd/s_user.c
--- ircu2.10-lain-vanilla/ircd/s_user.c	Sun May 20 22:09:13 2001
+++ ircu2.10-lain/ircd/s_user.c	Tue May 29 04:52:00 2001
@@ -672,6 +672,7 @@
   { FLAGS_WALLOP,      'w' },
   { FLAGS_SERVNOTICE,  's' },
   { FLAGS_DEAF,        'd' },
+  { FLAGS_HIDECHAN,    'n' },
   { FLAGS_CHSERV,      'k' },
   { FLAGS_DEBUG,       'g' }
 };
@@ -1200,6 +1201,16 @@
         else
           ClearInvisible(sptr);
         break;
+      case 'n':
+        if (what == MODE_ADD)
+        {
+          if(IsChannelService(sptr))
+            ClearChannelService(sptr);
+          SetHidechan(sptr);
+        }
+        else
+          ClearHidechan(sptr);
+        break;
       case 'd':
         if (what == MODE_ADD)
           SetDeaf(sptr);
@@ -1218,6 +1229,8 @@
       case 'k':
         if (what == MODE_ADD)
         {
+          if(IsHidechan(sptr))
+            ClearHidechan(sptr);
           SetChannelService(sptr);
           opt++;
         }
@@ -1275,6 +1288,10 @@
   } else {
     if (!(setflags & FLAGS_CHSERV) && !IsServer(cptr))
       ClearChannelService(sptr);
+  }
+  if(!(setflags & FLAGS_HIDECHAN) && !IsAnOper(sptr) && !IsServer(cptr))
+  {
+    ClearHidechan(sptr);
   }
   /*
    * Compare new flags with old flags and send string which
