--- /dev/null
+^\.hg
+^\.mq
+syntax: glob
+status
+guards
--- /dev/null
+make HACK notices for KICKs consitent with other HACK notices, add the type of HACK to the message (2 or 4)
+
+diff -r 9c1421eb77c1 ircd/m_kick.c
+--- a/ircd/m_kick.c Sun Jan 11 22:38:39 2009 +0000
++++ b/ircd/m_kick.c Sun Jan 11 22:38:39 2009 +0000
+@@ -239,7 +239,7 @@
+ if (IsServer(sptr) &&
+ !IsBurstOrBurstAck(sptr) &&
+ sptr!=cli_user(who)->server)
+- sendto_opmask_butone(0, SNO_HACK4, "HACK: %C KICK %H %C %s", sptr, chptr,
++ sendto_opmask_butone(0, SNO_HACK4, "HACK(4): %C KICK %H %C %s", sptr, chptr,
+ who, comment);
+
+ /* Unless someone accepted it downstream (or the user isn't on the channel
+@@ -248,7 +248,7 @@
+ */
+ if (!IsServer(sptr) && member && cli_from(who) != cptr &&
+ (!(sptr_link = find_member_link(chptr, sptr)) || !IsChanOp(sptr_link))) {
+- sendto_opmask_butone(0, SNO_HACK2, "HACK: %C KICK %H %C %s", sptr, chptr,
++ sendto_opmask_butone(0, SNO_HACK2, "HACK(2): %C KICK %H %C %s", sptr, chptr,
+ who, comment);
+
+ sendcmdto_one(who, CMD_JOIN, cptr, "%H", chptr);
--- /dev/null
+ircu uses nick chasing for whowas, but also for targetting /kill, /kick, /mode o/v, in case a nick isnt found, the whowas history is check and the intented victim is chased (time limit is 30 seconds)
+
+example without this patch:
+00:01 > NICK newnick
+00:01 > MODE oldnick +w
+00:01 < oldnick!user@host NICK newnick
+00:01 < irc.quakenet.org 403 newnick oldnick :no such channel
+usermode change failed because of the nick change getting in the way
+
+example with this patch:
+00:01 > NICK newnick
+00:01 > MODE oldnick +w
+00:01 < oldnick!user@host NICK newnick
+00:01 < newnick!user@host MODE newnick +w
+usermode change succeeded because ircd uses whowas history and found the previous user with this nick was this user
+much friendlier and simply achieved by using information already available
+
+diff -r ec3841c774be include/channel.h
+--- a/include/channel.h Sun Jan 11 22:38:38 2009 +0000
++++ b/include/channel.h Sun Jan 11 22:38:38 2009 +0000
+@@ -390,7 +390,7 @@
+ extern void make_zombie(struct Membership* member, struct Client* who,
+ struct Client* cptr, struct Client* sptr,
+ struct Channel* chptr);
+-extern struct Client* find_chasing(struct Client* sptr, const char* user, int* chasing);
++extern struct Client* find_chasing(struct Client* sptr, const char* user, int* chasing, int error);
+ void add_invite(struct Client *cptr, struct Channel *chptr);
+ int number_of_zombies(struct Channel *chptr);
+
+diff -r ec3841c774be ircd/channel.c
+--- a/ircd/channel.c Sun Jan 11 22:38:38 2009 +0000
++++ b/ircd/channel.c Sun Jan 11 22:38:38 2009 +0000
+@@ -218,9 +218,10 @@
+ * @param user a string representing the client to be found
+ * @param chasing a variable set to 0 if the user was found directly,
+ * 1 otherwise
++ * @param error send error to source when set to 1, else not
+ * @returns a pointer the client, or NULL if the client wasn't found.
+ */
+-struct Client* find_chasing(struct Client* sptr, const char* user, int* chasing)
++struct Client* find_chasing(struct Client* sptr, const char* user, int* chasing, int error)
+ {
+ struct Client* who = FindClient(user);
+
+@@ -230,7 +231,8 @@
+ return who;
+
+ if (!(who = get_history(user, feature_int(FEAT_KILLCHASETIMELIMIT)))) {
+- send_reply(sptr, ERR_NOSUCHNICK, user);
++ if (error)
++ send_reply(sptr, ERR_NOSUCHNICK, user);
+ return 0;
+ }
+ if (chasing)
+@@ -3120,7 +3122,7 @@
+ oplevel = req_oplevel;
+ }
+ /* find client we're manipulating */
+- acptr = find_chasing(state->sptr, t_str, NULL);
++ acptr = find_chasing(state->sptr, t_str, NULL,1);
+ } else {
+ if (t_str[5] == ':') {
+ t_str[5] = '\0';
+diff -r ec3841c774be ircd/m_kick.c
+--- a/ircd/m_kick.c Sun Jan 11 22:38:38 2009 +0000
++++ b/ircd/m_kick.c Sun Jan 11 22:38:38 2009 +0000
+@@ -127,7 +127,7 @@
+ || !IsChanOp(member2))
+ return send_reply(sptr, ERR_CHANOPRIVSNEEDED, name);
+
+- if (!(who = find_chasing(sptr, parv[2], 0)))
++ if (!(who = find_chasing(sptr, parv[2], 0,1)))
+ return 0; /* find_chasing sends the reply for us */
+
+ /* Don't allow the channel service to be kicked */
+diff -r ec3841c774be ircd/m_mode.c
+--- a/ircd/m_mode.c Sun Jan 11 22:38:38 2009 +0000
++++ b/ircd/m_mode.c Sun Jan 11 22:38:38 2009 +0000
+@@ -117,7 +117,7 @@
+ struct Client *acptr;
+
+ acptr = FindUser(parv[1]);
+- if (!acptr)
++ if (!(acptr = find_chasing(sptr, parv[1], 0,0)))
+ {
+ send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);
+ return 0;
--- /dev/null
+add opkick command, similar to opmode command, but then for kicking
+priv controlled by LOCAL_OPMODE and OPMODE
+feature controlled by OPKICK (disabled by default), new p10 token OK
+if implemented, it must not be enabled until ALL servers and services are upgraded
+generates HACK(4) snomask notice for accountability with oper as source
+probably needs some work (for one i simply copied the header from m_kick.c)
+
+diff -r f1d6c059e808 include/handlers.h
+--- a/include/handlers.h Sun Jan 11 22:38:39 2009 +0000
++++ b/include/handlers.h Sun Jan 11 22:38:39 2009 +0000
+@@ -167,6 +167,7 @@
+ extern int mo_kill(struct Client*, struct Client*, int, char*[]);
+ extern int mo_notice(struct Client*, struct Client*, int, char*[]);
+ extern int mo_oper(struct Client*, struct Client*, int, char*[]);
++extern int mo_opkick(struct Client*, struct Client*, int, char*[]);
+ extern int mo_opmode(struct Client*, struct Client*, int, char*[]);
+ extern int mo_ping(struct Client*, struct Client*, int, char*[]);
+ extern int mo_privmsg(struct Client*, struct Client*, int, char*[]);
+@@ -216,6 +217,7 @@
+ extern int ms_nick(struct Client*, struct Client*, int, char*[]);
+ extern int ms_notice(struct Client*, struct Client*, int, char*[]);
+ extern int ms_oper(struct Client*, struct Client*, int, char*[]);
++extern int ms_opkick(struct Client*, struct Client*, int, char*[]);
+ extern int ms_opmode(struct Client*, struct Client*, int, char*[]);
+ extern int ms_part(struct Client*, struct Client*, int, char*[]);
+ extern int ms_ping(struct Client*, struct Client*, int, char*[]);
+diff -r f1d6c059e808 include/ircd_features.h
+--- a/include/ircd_features.h Sun Jan 11 22:38:39 2009 +0000
++++ b/include/ircd_features.h Sun Jan 11 22:38:39 2009 +0000
+@@ -105,6 +105,7 @@
+ /* features that affect all operators */
+ FEAT_EXTENDED_CHECKCMD,
+ FEAT_CONFIG_OPERCMDS,
++ FEAT_OPKICK,
+ FEAT_SETHOST,
+ FEAT_SETHOST_USER,
+ FEAT_SETHOST_AUTO,
+diff -r f1d6c059e808 include/msg.h
+--- a/include/msg.h Sun Jan 11 22:38:39 2009 +0000
++++ b/include/msg.h Sun Jan 11 22:38:39 2009 +0000
+@@ -236,6 +236,10 @@
+ #define TOK_KICK "K"
+ #define CMD_KICK MSG_KICK, TOK_KICK
+
++#define MSG_OPKICK "OPKICK" /* OPKICK */
++#define TOK_OPKICK "OK"
++#define CMD_OPKICK MSG_OPKICK, TOK_OPKICK
++
+ #define MSG_USERHOST "USERHOST" /* USER -> USRH */
+ #define TOK_USERHOST "USERHOST"
+ #define CMD_USERHOST MSG_USERHOST, TOK_USERHOST
+diff -r f1d6c059e808 ircd/Makefile.in
+--- a/ircd/Makefile.in Sun Jan 11 22:38:39 2009 +0000
++++ b/ircd/Makefile.in Sun Jan 11 22:38:39 2009 +0000
+@@ -151,6 +151,7 @@
+ m_nick.c \
+ m_notice.c \
+ m_oper.c \
++ m_opkick.c \
+ m_opmode.c \
+ m_part.c \
+ m_pass.c \
+@@ -884,6 +885,14 @@
+ ../include/ircd_features.h ../include/s_conf.h ../include/client.h \
+ ../include/s_debug.h ../include/s_user.h ../include/s_misc.h \
+ ../include/send.h
++m_opkick.o: m_opkick.c ../config.h ../include/channel.h \
++ ../include/ircd_defs.h ../include/res.h ../config.h ../include/client.h \
++ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \
++ ../include/ircd_handler.h ../include/capab.h ../include/hash.h \
++ ../include/ircd.h ../include/struct.h ../include/ircd_log.h \
++ ../include/ircd_reply.h ../include/ircd_string.h \
++ ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \
++ ../include/numnicks.h ../include/send.h ../include/ircd_features.h
+ m_opmode.o: m_opmode.c ../config.h ../include/client.h \
+ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
+ ../include/ircd_events.h ../config.h ../include/ircd_handler.h \
+diff -r f1d6c059e808 ircd/ircd_features.c
+--- a/ircd/ircd_features.c Sun Jan 11 22:38:39 2009 +0000
++++ b/ircd/ircd_features.c Sun Jan 11 22:38:39 2009 +0000
+@@ -359,6 +359,7 @@
+ /* features that affect all operators */
+ F_B(EXTENDED_CHECKCMD, 0, 0, 0),
+ F_B(CONFIG_OPERCMDS, 0, 0, 0),
++ F_B(OPKICK, 0, 0, 0),
+ F_B(SETHOST, 0, 0, 0),
+ F_B(SETHOST_USER, 0, 0, 0),
+ F_B(SETHOST_AUTO, 0, 0, 0),
+diff -r f1d6c059e808 ircd/parse.c
+--- a/ircd/parse.c Sun Jan 11 22:38:39 2009 +0000
++++ b/ircd/parse.c Sun Jan 11 22:38:39 2009 +0000
+@@ -656,6 +656,17 @@
+ 0, MAXPARA, MFLG_SLOW, 0, NULL,
+ { m_unregistered, m_not_oper, m_check, m_check, m_ignore }
+ },
++
++ /*
++ * Add the command for OPKICK.
++ */
++ {
++ MSG_OPKICK,
++ TOK_OPKICK,
++ 0, MAXPARA, MFLG_SLOW, 0, NULL,
++ /* UNREG, CLIENT, SERVER, OPER, SERVICE */
++ { m_unregistered, m_not_oper, ms_opkick, mo_opkick, m_ignore }
++ },
+
+ /* This command is an alias for QUIT during the unregistered part of
+ * of the server. This is because someone jumping via a broken web
--- /dev/null
+kicking of a delayedjoin user by a chanop is shown to ALL chanops on the channel, for accountability reasons (instead of only to source and victim)
+
+diff -r c4d8c0416ae6 ircd/m_kick.c
+--- a/ircd/m_kick.c Sun Jan 11 22:38:38 2009 +0000
++++ b/ircd/m_kick.c Sun Jan 11 22:38:39 2009 +0000
+@@ -176,11 +176,17 @@
+
+ if (IsDelayedJoin(member)) {
+ /* If it's a delayed join, only send the KICK to the person doing
+- * the kicking and the victim */
++ * the kicking and the victim
++ * ok, but accountability among chanops:
++ * a chanop kicks the victim, tell the other chanops about his action,
++ * join the victim to the channel, followed by the kick
++ */
+ if (MyUser(who))
+ sendcmdto_one(sptr, CMD_KICK, who, "%H %C :%s", chptr, who, comment);
+- sendcmdto_one(who, CMD_JOIN, sptr, "%H", chptr);
+- sendcmdto_one(sptr, CMD_KICK, sptr, "%H %C :%s", chptr, who, comment);
++ sendcmdto_channel_butserv_butone(who, CMD_JOIN, chptr, NULL, SKIP_NONOPS,
++ "%H", chptr);
++ sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, SKIP_NONOPS,
++ "%H %C :%s", chptr, who, comment);
+ CheckDelayedJoins(chptr);
+ } else
+ sendcmdto_channel_butserv_butone((IsServer(sptr) ? &me : sptr), CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who,
+@@ -270,6 +276,16 @@
+
+ if (member) { /* and tell the channel about it */
+ if (IsDelayedJoin(member)) {
++ /* accountability among chanops:
++ * a chanop kicks the victim, tell the other chanops about his action,
++ * join the victim to the channel, followed by the kick
++ */
++ if (IsUser(sptr)) {
++ sendcmdto_channel_butserv_butone(who, CMD_JOIN, chptr, NULL, SKIP_NONOPS,
++ "%H", chptr);
++ sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, SKIP_NONOPS,
++ "%H %C :%s", chptr, who, comment);
++ }
+ if (MyUser(who))
+ sendcmdto_one(IsServer(sptr) ? &his : sptr, CMD_KICK,
+ who, "%H %C :%s", chptr, who, comment);
--- /dev/null
+corrects some output in /stats V/v
+show flags for own server correct, changed n to N
+
+diff -r 32cd51bef571 ircd/s_stats.c
+--- a/ircd/s_stats.c Sun Jan 11 22:38:38 2009 +0000
++++ b/ircd/s_stats.c Sun Jan 11 22:38:38 2009 +0000
+@@ -513,10 +513,10 @@
+ cli_name(cli_serv(acptr)->up),
+ IsBurst(acptr) ? 'B' : '-',
+ IsBurstAck(acptr) ? 'A' : '-',
+- IsHub(acptr) ? 'H' : '-',
++ (IsHub(acptr) || (IsMe(acptr) && (feature_bool(FEAT_HUB)))) ? 'H' : '-',
+ IsService(acptr) ? 'S' : '-',
+- IsIPv6(acptr) ? '6' : '-',
+- IsSendOperName(acptr) ? 'n' : '-',
++ (IsIPv6(acptr) || IsMe(acptr)) ? '6' : '-',
++ (IsSendOperName(acptr) || IsMe(acptr)) ? 'N' : '-',
+ cli_hopcount(acptr),
+ NumServ(acptr),
+ base64toint(cli_yxx(acptr)),
--- /dev/null
+SNO_GLINE and SNO_AUTO
+before, glines with reason starting with "AUTO" end up in SNO_AUTO, all other in SNO_GLINE
+now
+/* figure out what snomask to send to, send to SNO_GLINE when:
+* source is a user and is not on a service server
+* gline is local, a badchan, or a realname gline
+* duration is either 120 seconds or less, or 2 weeks or more
+* nick part is not equal to *
+* the gline is wide
+* otherwise, send to SNO_AUTO
+*/
+
+diff -r 16b56cea76d8 ircd/gline.c
+--- a/ircd/gline.c Sun Jan 11 22:38:40 2009 +0000
++++ b/ircd/gline.c Sun Jan 11 22:38:41 2009 +0000
+@@ -209,7 +209,7 @@
+ * @return Zero, unless \a sptr G-lined himself, in which case CPTR_KILLED.
+ */
+ static int
+-do_gline(struct Client *cptr, struct Client *sptr, struct Gline *gline)
++do_gline(struct Client *cptr, struct Client *sptr, struct Gline *gline, int snomask)
+ {
+ struct Client *acptr;
+ int fd, retval = 0, tval;
+@@ -278,7 +278,7 @@
+ gline->gl_reason);
+
+ /* let the ops know about it */
+- sendto_opmask_butone(0, SNO_GLINE, "G-line active for %s",
++ sendto_opmask_butone(0, snomask, "G-line active for %s",
+ get_client_name(acptr, SHOW_IP));
+
+ /* and get rid of him */
+@@ -470,6 +470,7 @@
+ char uhmask[NICKLEN + USERLEN + HOSTLEN + 3];
+ char *nick, *user, *host;
+ int tmp;
++ int snomask;
+
+ assert(0 != userhost);
+ assert(0 != reason);
+@@ -543,9 +544,25 @@
+
+ /* lifetime is already an absolute timestamp */
+
++ /* figure out what snomask to send to, send to SNO_GLINE when:
++ * source is a user and is not on a service server
++ * gline is local, a badchan, or a realname gline
++ * duration is either 120 seconds or less, or 2 weeks or more
++ * nick part is not equal to *
++ * the gline is wide
++ * otherwise, send to SNO_AUTO
++ */
++ if ((IsUser(sptr) && !IsService(cli_user(sptr)->server)) ||
++ (flags & (GLINE_LOCAL|GLINE_BADCHAN|GLINE_REALNAME)) ||
++ ((expire - CurrentTime <= 120) || (expire - CurrentTime >= 1209600)) ||
++ !(nick[0] == '*' && nick[1] == '\0') ||
++ (gline_checkmask(host) != CHECK_APPROVED))
++ snomask = SNO_GLINE;
++ else
++ snomask = SNO_AUTO;
++
+ /* Inform ops... */
+- sendto_opmask_butone(0, ircd_strncmp(reason, "AUTO", 4) ? SNO_GLINE :
+- SNO_AUTO, "%s adding %s %s for %s%s%s%s%s, expiring at "
++ sendto_opmask_butone(0, snomask, "%s adding %s %s for %s%s%s%s%s, expiring at "
+ "%Tu: %s",
+ (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
+ cli_name(sptr) :
+@@ -581,7 +598,7 @@
+
+ gline_propagate(cptr, sptr, agline);
+
+- return do_gline(cptr, sptr, agline); /* knock off users if necessary */
++ return do_gline(cptr, sptr, agline, snomask); /* knock off users if necessary */
+ }
+
+ /** Activate a currently inactive G-line.
+@@ -644,7 +661,7 @@
+ if (!(flags & GLINE_LOCAL)) /* don't propagate local changes */
+ gline_propagate(cptr, sptr, gline);
+
+- return do_gline(cptr, sptr, gline);
++ return do_gline(cptr, sptr, gline, SNO_GLINE);
+ }
+
+ /** Deactivate a G-line.
+@@ -928,7 +945,7 @@
+ gline->gl_lifetime, gline->gl_reason);
+
+ /* OK, let's do the G-line... */
+- return do_gline(cptr, sptr, gline);
++ return do_gline(cptr, sptr, gline, SNO_GLINE);
+ }
+
+ /** Destroy a local G-line.
--- /dev/null
+hide the owner of a ban in the channel banlist from non-chanops
+
+diff -r 67928388e226 ircd/channel.c
+--- a/ircd/channel.c Sun Jan 11 22:38:39 2009 +0000
++++ b/ircd/channel.c Sun Jan 11 22:38:40 2009 +0000
+@@ -1243,13 +1243,18 @@
+ static void send_ban_list(struct Client* cptr, struct Channel* chptr)
+ {
+ struct Ban* lp;
++ int showbanowner = 0;
+
+ assert(0 != cptr);
+ assert(0 != chptr);
+
++ /* hide who set the ban from non-chanops */
++ if (IsAnOper(cptr) || is_chan_op(cptr, chptr))
++ showbanowner = 1;
++
+ for (lp = chptr->banlist; lp; lp = lp->next)
+ send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr,
+- lp->who, lp->when);
++ showbanowner ? lp->who : "*", lp->when);
+
+ send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname);
+ }
--- /dev/null
+allows ordinary users to specify a remote server, and only throws an error when it doesnt match the local server - inconsistent with many other irc commands (names info motd etc.)
+
+diff -r f9d3f3500a68 ircd/m_admin.c
+--- a/ircd/m_admin.c Sun Jan 11 22:38:40 2009 +0000
++++ b/ircd/m_admin.c Sun Jan 11 22:38:40 2009 +0000
+@@ -120,7 +120,7 @@
+ assert(0 != cptr);
+ assert(cptr == sptr);
+
+- if (parc > 1 && match(parv[1], cli_name(&me)))
++ if (parc > 1)
+ return send_reply(sptr, ERR_NOPRIVILEGES);
+
+ return send_admin_info(sptr);
--- /dev/null
+tidy up HIS G-line/K-line reasons, instead of examing the quit reason, set a flag and use that to determine whether or not the quit reason shown to other users should be altered.
+
+diff -r b737284f4c26 include/client.h
+--- a/include/client.h Sun Jan 11 22:38:41 2009 +0000
++++ b/include/client.h Sun Jan 11 22:38:41 2009 +0000
+@@ -156,6 +156,8 @@
+ FLAG_PINGSENT, /**< Unreplied ping sent */
+ FLAG_DEADSOCKET, /**< Local socket is dead--Exiting soon */
+ FLAG_KILLED, /**< Prevents "QUIT" from being sent for this */
++ FLAG_KLINED, /**< HIS K-line reasons, prevents K-line reason from being shown to others */
++ FLAG_GLINED, /**< HIS G-line reasons, prevents G-line reason from being shown to others */
+ FLAG_BLOCKED, /**< socket is in a blocked condition */
+ FLAG_CLOSING, /**< set when closing to suppress errors */
+ FLAG_UPING, /**< has active UDP ping request */
+diff -r b737284f4c26 ircd/gline.c
+--- a/ircd/gline.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/gline.c Sun Jan 11 22:38:41 2009 +0000
+@@ -282,9 +282,10 @@
+ get_client_name(acptr, SHOW_IP));
+
+ /* and get rid of him */
+- /* WARNING: code in exit_client() relies on the quit message starting with
+- * G-lined or K-lined for HIS purposes
++ /* set FLAG_GLINED for HIS function
++ * prevents G-line reason from being shown to other users
+ */
++ SetFlag(acptr, FLAG_GLINED);
+ if ((tval = exit_client_msg(cptr, acptr, &me, "G-lined (%s)", gline->gl_reason)))
+ retval = tval; /* retain killed status */
+ }
+diff -r b737284f4c26 ircd/s_auth.c
+--- a/ircd/s_auth.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/s_auth.c Sun Jan 11 22:38:41 2009 +0000
+@@ -270,9 +270,10 @@
+ killreason = find_kill(sptr, 1, &reason);
+ if (killreason) {
+ ServerStats->is_ref++;
+- /* WARNING: code in exit_client() relies on the quit message starting with
+- * G-lined or K-lined for HIS purposes
+- */
++ /* set FLAG_KLINED or FLAG_GLINED for HIS function
++ * prevents K-line and G-line reason from being shown to other users
++ */
++ SetFlag(sptr, killreason == -1 ? FLAG_KLINED : FLAG_GLINED);
+ return exit_client_msg(sptr, sptr, &me, "%s (%s)",
+ (killreason == -1 ? "K-lined" : "G-lined"), reason);
+ }
+diff -r b737284f4c26 ircd/s_conf.c
+--- a/ircd/s_conf.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/s_conf.c Sun Jan 11 22:38:41 2009 +0000
+@@ -993,9 +993,10 @@
+ "K-line active for %s%s",
+ IsUnknown(acptr) ? "Unregistered Client ":"",
+ get_client_name(acptr, SHOW_IP));
+- /* WARNING: code in exit_client() relies on the quit message starting with
+- * G-lined or K-lined for HIS purposes
+- */
++ /* set FLAG_KLINED or FLAG_GLINED for HIS function
++ * prevents K-line and G-line reason from being shown to other users
++ */
++ SetFlag(acptr, found_g == -2 ? FLAG_GLINED : FLAG_KLINED);
+ if (exit_client_msg(cptr, acptr, &me, "%s (%s)", found_g == -2 ? "G-lined" :
+ "K-lined", reason) == CPTR_KILLED)
+ ret = CPTR_KILLED;
+diff -r b737284f4c26 ircd/s_misc.c
+--- a/ircd/s_misc.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/s_misc.c Sun Jan 11 22:38:41 2009 +0000
+@@ -496,11 +496,24 @@
+ sendcmdto_one(killer, CMD_SQUIT, dlp->value.cptr, "%s %Tu :%s",
+ cli_name(victim), cli_serv(victim)->timestamp, comment);
+ else if (IsUser(victim) && !HasFlag(victim, FLAG_KILLED)) {
+- /* do not show G-line or K-line reasons to other users, so remove them - wiebe */
+- if (!strncmp(comment, "G-lined", 7))
+- comment = "G-lined";
+- else if (!strncmp(comment, "K-lined", 7))
+- comment = "K-lined";
++ /* my user is hit by K-line or G-line, hide the reason */
++ if (MyUser(victim)) {
++ if (HasFlag(victim, FLAG_KLINED))
++ comment = "K-lined";
++ else if (HasFlag(victim, FLAG_GLINED))
++ comment = "G-lined";
++ } else {
++ /* backwards compatibility
++ * remove G-line and K-line reasons from quits from remote users
++ * as snircd 1.3.x still sends those upstream
++ * this part of the code can be removed for the next snircd release
++ * December 2008 - wiebe
++ */
++ if (!strncmp(comment, "G-lined", 7))
++ comment = "G-lined";
++ else if (!strncmp(comment, "K-lined", 7))
++ comment = "K-lined";
++ }
+ sendcmdto_one(victim, CMD_QUIT, dlp->value.cptr, ":%s", comment);
+ }
+ }
--- /dev/null
+same as 42 but then for version, tidied up a bit, and use hunt_server_cmd to find and forward remote requests to, rather than doing that work itself in the various *_version functions.
+
+diff -r 2fe969629892 ircd/m_version.c
+--- a/ircd/m_version.c Sun Jan 11 22:38:40 2009 +0000
++++ b/ircd/m_version.c Sun Jan 11 22:38:40 2009 +0000
+@@ -109,7 +109,7 @@
+ */
+ int m_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
+ {
+- if (parc > 1 && match(parv[1], cli_name(&me)))
++ if (parc > 1)
+ return send_reply(sptr, ERR_NOPRIVILEGES);
+
+ send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
+@@ -129,26 +129,16 @@
+ struct Client *acptr;
+ char *target=parv[1];
+
+- if (MyConnect(sptr) && parc > 1)
+- {
+- /* Send version request to all servers when * is given as parameter */
+- if (target[0] == '*' && target[1] == '\0') {
+- sendcmdto_serv_butone(sptr, CMD_VERSION, cptr, ":%s", target);
+- send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
+- debug_serveropts());
+- return 0;
+- }
+- if (!(acptr = find_match_server(target))) {
+- send_reply(sptr, ERR_NOSUCHSERVER, target);
+- return 0;
+- }
+- target = cli_name(acptr);
++ /* Send version request to all servers when * is given as parameter */
++ if (parc > 1 && target[0] == '*' && target[1] == '\0') {
++ sendcmdto_serv_butone(sptr, CMD_VERSION, cptr, ":%s", target);
++ send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
++ debug_serveropts());
++ return 0;
+ }
+
+ if (hunt_server_cmd(sptr, CMD_VERSION, cptr, feature_int(FEAT_HIS_REMOTE),
+- ":%C", 1,
+- parc, parv)
+- == HUNTED_ISME)
++ ":%C", 1, parc, parv) == HUNTED_ISME)
+ {
+ send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
+ debug_serveropts());
+@@ -169,18 +159,8 @@
+ struct Client *acptr;
+ char *target=parv[1];
+
+- if (MyConnect(sptr) && parc > 1)
+- {
+- if (!(acptr = find_match_server(target)))
+- {
+- send_reply(sptr, ERR_NOSUCHSERVER, target);
+- return 0;
+- }
+- target = cli_name(acptr);
+- }
+-
+ /* Version request with parameter *, send my version info and pass on the request */
+- if (target[0] == '*' && target[1] == '\0')
++ if (parc > 1 && target[0] == '*' && target[1] == '\0')
+ {
+ sendcmdto_serv_butone(sptr, CMD_VERSION, cptr, ":%s", target);
+ send_reply(sptr, RPL_VERSION, version, debugmode, cli_name(&me),
--- /dev/null
+excludes clients with usermode +k / +X or the privs to set them from netrider kick
+
+diff -r 41ce42398a8f ircd/m_burst.c
+--- a/ircd/m_burst.c Sun Jan 11 18:08:49 2009 +0000
++++ b/ircd/m_burst.c Sun Jan 11 22:38:38 2009 +0000
+@@ -299,6 +299,12 @@
+ nmember = member->next_member;
+ if (!MyUser(member->user) || IsZombie(member))
+ continue;
++ /* Do not kick +k user or operator with priv to set it */
++ if (IsChannelService(member->user) || HasPriv(member->user, PRIV_CHANSERV))
++ continue;
++ /* Do not kick +X user or operator with priv to set it */
++ if (IsXtraOp(member->user) || HasPriv(member->user, PRIV_XTRA_OPER))
++ continue;
+ /* Kick as netrider if key mismatch *or* remote channel is
+ * +i (unless user is an oper) *or* remote channel is +r
+ * (unless user has an account).
--- /dev/null
+netriderexemptumodekbigxpriv.patch
+fixstatsv.patch
+addnickchasetomodenick.patch
+chanopaccountabilityforkickdelayedjoin.patch
+addopkickcmd.patch
+addhacktypetohackkick.patch
+hidebanowner.patch
+hisadmin.patch
+hisversionremote.patch
+glinesnomask.patch
+hiskgline.patch
+whotopic.patch
--- /dev/null
+topic by info is either 'nick' or '*account'
+
+diff -r d1464f64b223 include/channel.h
+--- a/include/channel.h Sun Jan 11 22:38:41 2009 +0000
++++ b/include/channel.h Sun Jan 11 22:38:41 2009 +0000
+@@ -285,9 +285,10 @@
+ struct Mode mode; /**< This channels mode */
+ unsigned int marker; /**< Channel marker */
+ char topic[TOPICLEN + 1]; /**< Channels topic */
+- char topic_nick[NICKLEN + 1]; /**< Nick of the person who set
++ char topic_who[ACCOUNTLEN > NICKLEN ? ACCOUNTLEN+1 : NICKLEN+1]; /**< Nick or account of the person who set
+ * The topic
+ */
++ int topic_who_is_account; /**< 0 when topic_who is nick, 1 when an account */
+ char chname[1]; /**< Dynamically allocated string of the
+ * channel name
+ */
+diff -r d1464f64b223 ircd/m_burst.c
+--- a/ircd/m_burst.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/m_burst.c Sun Jan 11 22:38:41 2009 +0000
+@@ -369,7 +369,8 @@
+ /* clear topic set by netrider (if set) */
+ if (*chptr->topic) {
+ *chptr->topic = '\0';
+- *chptr->topic_nick = '\0';
++ *chptr->topic_who = '\0';
++ chptr->topic_who_is_account = 0;
+ chptr->topic_time = 0;
+ sendcmdto_channel_butserv_butone(&his, CMD_TOPIC, chptr, NULL, 0,
+ "%H :%s", chptr, chptr->topic);
+diff -r d1464f64b223 ircd/m_check.c
+--- a/ircd/m_check.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/m_check.c Sun Jan 11 22:38:41 2009 +0000
+@@ -380,7 +380,8 @@
+ send_reply(sptr, RPL_DATASTR, outbuf);
+
+ /* ..set by */
+- ircd_snprintf(sptr, outbuf, sizeof(outbuf), " Set by:: %s", chptr->topic_nick);
++ ircd_snprintf(sptr, outbuf, sizeof(outbuf), " Set by:: %s%s",
++ chptr->topic_who_is_account ? "*" : "", chptr->topic_who);
+ send_reply(sptr, RPL_DATASTR, outbuf);
+
+ ircd_snprintf(sptr, outbuf, sizeof(outbuf), " Set at:: %s (%Tu)", myctime(chptr->topic_time), chptr->topic_time);
+diff -r d1464f64b223 ircd/m_join.c
+--- a/ircd/m_join.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/m_join.c Sun Jan 11 22:38:41 2009 +0000
+@@ -283,7 +283,9 @@
+
+ if (chptr->topic[0]) {
+ send_reply(sptr, RPL_TOPIC, chptr->chname, chptr->topic);
+- send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
++ send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname,
++ chptr->topic_who_is_account ? "*" : "",
++ chptr->topic_who,
+ chptr->topic_time);
+ }
+
+diff -r d1464f64b223 ircd/m_topic.c
+--- a/ircd/m_topic.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/m_topic.c Sun Jan 11 22:38:41 2009 +0000
+@@ -65,7 +65,10 @@
+ newtopic=ircd_strncmp(chptr->topic,topic,TOPICLEN)!=0;
+ /* setting a topic */
+ ircd_strncpy(chptr->topic, topic, TOPICLEN);
+- ircd_strncpy(chptr->topic_nick, cli_name(from), NICKLEN);
++ ircd_strncpy(chptr->topic_who,
++ IsAccount(from) ? cli_user(from)->account : cli_name(from),
++ IsAccount(from) ? ACCOUNTLEN : NICKLEN);
++ chptr->topic_who_is_account = IsAccount(from) ? 1 : 0;
+ chptr->topic_time = ts ? ts : TStime();
+ /* Fixed in 2.10.11: Don't propagate local topics */
+ if (!IsLocalChannel(chptr->chname))
+@@ -129,7 +132,9 @@
+ else
+ {
+ send_reply(sptr, RPL_TOPIC, chptr->chname, chptr->topic);
+- send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
++ send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname,
++ chptr->topic_who_is_account ? "*" : "",
++ chptr->topic_who,
+ chptr->topic_time);
+ }
+ }
+diff -r d1464f64b223 ircd/s_err.c
+--- a/ircd/s_err.c Sun Jan 11 22:38:41 2009 +0000
++++ b/ircd/s_err.c Sun Jan 11 22:38:41 2009 +0000
+@@ -698,7 +698,7 @@
+ /* 332 */
+ { RPL_TOPIC, "%s :%s", "332" },
+ /* 333 */
+- { RPL_TOPICWHOTIME, "%s %s %Tu", "333" },
++ { RPL_TOPICWHOTIME, "%s %s%s %Tu", "333" },
+ /* 334 */
+ { RPL_LISTUSAGE, ":%s", "334" },
+ /* 335 */