]> jfr.im git - irc/quakenet/snircd.git/commitdiff
forward port of asuka-kX.patch to .12
authorpaul <redacted>
Sun, 23 Oct 2005 21:15:00 +0000 (22:15 +0100)
committerpaul <redacted>
Sun, 23 Oct 2005 21:15:00 +0000 (22:15 +0100)
note: check whocmds.c part of this patch

12 files changed:
include/client.h
include/ircd_features.h
include/numeric.h
ircd/channel.c
ircd/ircd_features.c
ircd/m_join.c
ircd/m_kick.c
ircd/m_kill.c
ircd/m_whois.c
ircd/s_err.c
ircd/s_user.c
ircd/whocmds.c

index ae632bda5e2c4705bde83cef4befc9d5b1e8c7ad..ce6ebadccd640c8ad7b0fb0a9c9c2f3a1bfab69b 100644 (file)
@@ -90,7 +90,7 @@ typedef unsigned long flagpage_t;
 #define FlagClr(set,flag) ((set)->bits[FLAGSET_INDEX(flag)] &= ~FLAGSET_MASK(flag))
 
 /** String containing valid user modes, in no particular order. */
-#define infousermodes "dioswkgxR"
+#define infousermodes "dioswkgxRXIn"
 
 /** Operator privileges. */
 enum Priv
@@ -169,6 +169,10 @@ enum Flag
     FLAG_ACCOUNTONLY,               /**< ASUKA_R: hide privmsgs/notices if
                                      user is not authed or opered */
     FLAG_HIDDENHOST,                /**< user's host is hidden */
+    FLAG_NOCHAN,                    /**< user's channels are hidden */
+    FLAG_NOIDLE,                    /**< user's idletime is hidden */
+    FLAG_XTRAOP,                    /**< oper has special powers */
+
     FLAG_LAST_FLAG,                 /**< number of flags */
     FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */
     FLAG_GLOBAL_UMODES = FLAG_OPER  /**< First global mode flag */
@@ -606,6 +610,12 @@ struct Client {
 #define IsAccount(x)            HasFlag(x, FLAG_ACCOUNT)
 /** Return non-zero if the client has set mode +x (hidden host). */
 #define IsHiddenHost(x)         HasFlag(x, FLAG_HIDDENHOST)
+/** Return non-zero if the client has set mode +X (xtraop) */
+#define IsXtraOp(x)             HasFlag(x, FLAG_XTRAOP)
+/** Return non-zero if the client has set mode +n (hide channels) */
+#define IsNoChan(x)             HasFlag(x, FLAG_NOCHAN)
+/** Return non-zero if the client has set mode +I (hide idletime) */
+#define IsNoIdle(x)             HasFlag(x, FLAG_NOIDLE)
 /** Return non-zero if the client has an active PING request. */
 #define IsPingSent(x)           HasFlag(x, FLAG_PINGSENT)
 /** Return non-zero if the client should not receive privmsgs/notices
@@ -657,6 +667,12 @@ struct Client {
 #define SetAccount(x)           SetFlag(x, FLAG_ACCOUNT)
 /** Mark a client as having mode +x (hidden host). */
 #define SetHiddenHost(x)        SetFlag(x, FLAG_HIDDENHOST)
+/** Mark a client as having mode +X (xtraop). */
+#define SetXtraOp(x)            SetFlag(x, FLAG_XTRAOP)
+/** Mark a client as having mode +n (hide channels). */
+#define SetNoChan(x)            SetFlag(x, FLAG_NOCHAN)
+/** Mark a client as having mode +I (hide idletime). */
+#define SetNoIdle(x)            SetFlag(x, FLAG_NOIDLE)
 /** Mark a client as having a pending PING. */
 #define SetPingSent(x)          SetFlag(x, FLAG_PINGSENT)
 /** Mark a client as having mode +R (account only). */
@@ -692,6 +708,12 @@ struct Client {
 #define ClearServNotice(x)      ClrFlag(x, FLAG_SERVNOTICE)
 /** Remove mode +x (hidden host) from the client. */
 #define ClearHiddenHost(x)      ClrFlag(x, FLAG_HIDDENHOST)
+/** Remove mode +X (xtraop) from a client. */
+#define ClearXtraOp(x)          ClrFlag(x, FLAG_XTRAOP)
+/** Remove mode +n (hide channels) from a client. */
+#define ClearNoChan(x)          ClrFlag(x, FLAG_NOCHAN)
+/** Remove mode +I (hide idletime) from a client. */
+#define ClearNoIdle(x)          ClrFlag(x, FLAG_NOIDLE)
 /** Clear the client's pending PING flag. */
 #define ClearPingSent(x)        ClrFlag(x, FLAG_PINGSENT)
 /** Remove mode +R (account only) from a client */
index 753c695db9c943a9150590b7ed925b95d866a402..ccba85fdfe41b348d3fbb267ebcc93383fc03483 100644 (file)
@@ -56,6 +56,7 @@ enum Feature {
   FEAT_HIDDEN_IP,
   FEAT_AUTOINVISIBLE,
   FEAT_CONNEXIT_NOTICES,
+  FEAT_USER_HIDECHANS,
   FEAT_OPLEVELS,
   FEAT_LOCAL_CHANNELS,
   FEAT_TOPIC_BURST,
index 57f05d2c2261702bc7f63104ed9172bc53ffd931..939561ab494af2554b680bcf0fd3592672ece502 100644 (file)
@@ -409,6 +409,7 @@ extern const struct Numeric* get_error_numeric(int err);
 /*     ERR_DESYNC           484         Dalnet,PTlink */
 /*     ERR_ATTACKDENY       484         unreal */
 /*     ERR_RESTRICTED       484           IRCnet extension */
+#define ERR_ISREALSERVICE    485        /* QuakeNet/ASUKA extension */
 /*      ERR_UNIQOPRIVSNEEDED 485           IRCnet extension */
 /*     ERR_KILLDENY         485           unreal */
 /*     ERR_CANTKICKADMIN    485           PTlink */
index e6bc932985b5161f19c753896da230c1d0fe9a2f..2a2d2115e593000dd1365712515e54b30b58f8a2 100644 (file)
@@ -707,7 +707,7 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r
   /*
    * Servers can always speak on channels.
    */
-  if (IsServer(cptr))
+  if (IsServer(cptr) || IsXtraOp(cptr))
     return 1;
 
   member = find_channel_member(cptr, chptr);
@@ -2976,17 +2976,29 @@ mode_process_clients(struct ParseState *state)
     if ((state->cli_change[i].flag & (MODE_DEL | MODE_CHANOP)) ==
        (MODE_DEL | MODE_CHANOP)) {
       /* prevent +k users from being deopped */
-      if (IsChannelService(state->cli_change[i].client)) {
+      /*
+       * ASUKA_X:
+       * Allow +X'ed users to mess with +k'ed.
+       * --Bigfoot
+       */
+      if ((IsChannelService(state->cli_change[i].client) && IsService(cli_user(state->cli_change[i].client)->server)) || (IsChannelService(state->cli_change[i].client) && !IsXtraOp(state->sptr))) {
        if (state->flags & MODE_PARSE_FORCE) /* it was forced */
          sendto_opmask_butone(0, SNO_HACK4, "Deop of +k user on %H by %s",
                               state->chptr,
                               (IsServer(state->sptr) ? cli_name(state->sptr) :
                                cli_name((cli_user(state->sptr))->server)));
 
-       else if (MyUser(state->sptr) && state->flags & MODE_PARSE_SET) {
-         send_reply(state->sptr, ERR_ISCHANSERVICE,
-                    cli_name(state->cli_change[i].client),
-                    state->chptr->chname);
+        else if (MyUser(state->sptr) && state->flags & MODE_PARSE_SET && (state->sptr != state->cli_change[i].client)) {
+          if(IsService(cli_user(state->cli_change[i].client)->server) && IsChannelService(state->cli_change[i].client)){
+            send_reply(state->sptr, ERR_ISREALSERVICE,
+                     cli_name(state->cli_change[i].client),
+                     state->chptr->chname);
+          }else{
+            send_reply(state->sptr, ERR_ISCHANSERVICE,
+                     cli_name(state->cli_change[i].client),
+                     state->chptr->chname);
+          }
+
          continue;
        }
       }
index 088880f2602b2d9ee9e7e9cac04394f849ce7da7..92e0d022bf0f985b77ff2d3dc9136be6f4bea799 100644 (file)
@@ -309,6 +309,7 @@ static struct FeatureDesc {
   F_S(HIDDEN_IP, 0, "127.0.0.1", 0),
   F_B(AUTOINVISIBLE, 0, 1, 0),
   F_B(CONNEXIT_NOTICES, 0, 0, 0),
+  F_B(USER_HIDECHANS, 0, 0, 0),
   F_B(OPLEVELS, 0, 1, 0),
   F_B(LOCAL_CHANNELS, 0, 1, 0),
   F_B(TOPIC_BURST, 0, 0, 0),
index 1d75c65933e50db61daf3317d52ca6990de1fb5d..641e8e2e52e90e7277da52633c1c4093cf400648 100644 (file)
@@ -205,6 +205,14 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
       else if (*chptr->mode.key && (!key || strcmp(key, chptr->mode.key)))
         err = ERR_BADCHANNELKEY;
 
+      /*
+       * ASUKA_X:
+       * Allow XtraOpers to join all channels.
+       * --Bigfoot
+       */
+      if (IsXtraOp(sptr))
+        err = 0;
+      
       /* An oper with WALK_LCHAN privilege can join a local channel
        * he otherwise could not join by using "OVERRIDE" as the key.
        * This will generate a HACK(4) notice, but fails if the oper
index 988ad81335b724bbc0053246a88624b9ddbadec7..daf44b46c24f1f419674f71a30efe37c684b9429 100644 (file)
@@ -131,7 +131,15 @@ int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     return 0; /* find_chasing sends the reply for us */
 
   /* Don't allow the channel service to be kicked */
-  if (IsChannelService(who))
+  /*
+   * ASUKA_X:
+   * Allow +X'ed users to kick +k'ed, but not U-lined services.
+   * --Bigfoot
+   */
+  if (IsChannelService(who) && IsService(cli_user(who)->server))
+    return send_reply(sptr, ERR_ISREALSERVICE, cli_name(who), chptr->chname);
+
+  if (IsChannelService(who) && !IsXtraOp(sptr) && (who!=sptr))
     return send_reply(sptr, ERR_ISCHANSERVICE, cli_name(who), chptr->chname);
 
   /* Prevent kicking opers from local channels -DM- */
index 24ade1d71f456fb70c3d0026f756e41a5880619f..5e9f4d0d1ba740b16297058bef710ce1ae5a3edf 100644 (file)
@@ -277,7 +277,15 @@ int mo_kill(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   /*
    * if the user is +k, prevent a kill from local user
    */
-  if (IsChannelService(victim))
+  /*
+   * ASUKA_X:
+   * Allow +X'ed users to kill +k'ed, but not U-lined services.
+   * --Bigfoot
+   */
+  if (IsChannelService(victim) && IsService(cli_user(victim)->server))
+    return send_reply(sptr, ERR_ISREALSERVICE, "KILL", cli_name(victim));
+
+  if (IsChannelService(victim) && !IsXtraOp(sptr) && !(victim==sptr))
     return send_reply(sptr, ERR_ISCHANSERVICE, "KILL", cli_name(victim));
 
 
index ed7f1246f4fb094378c13588bd8a66dd1adeef3d..fec4b53074d7e78829c013e2bbaac3467153ec72 100644 (file)
@@ -144,7 +144,7 @@ static void do_whois(struct Client* sptr, struct Client *acptr, int parc)
                   cli_info(acptr));
 
   /* Display the channels this user is on. */
-  if (!IsChannelService(acptr))
+  if ((!IsChannelService(acptr) && !IsNoChan(acptr)) || (acptr==sptr))
   {
     struct Membership* chan;
     mlen = strlen(cli_name(&me)) + strlen(cli_name(sptr)) + 12 + strlen(name);
@@ -219,8 +219,10 @@ static void do_whois(struct Client* sptr, struct Client *acptr, int parc)
      *       probably a good place to add them :)
      */
 
-    if (MyConnect(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
-                             (sptr == acptr || IsAnOper(sptr) || parc >= 3)))
+    if (MyConnect(acptr) &&
+        (IsAnOper(sptr) ||
+         (!IsNoIdle(acptr) && (!feature_bool(FEAT_HIS_WHOIS_IDLETIME) ||
+                              sptr == acptr || parc >= 3))))
        send_reply(sptr, RPL_WHOISIDLE, name, CurrentTime - user->last,
                   cli_firsttime(acptr));
   }
index ad3abcd59ae6556fb03e7a6d7f23b0fbaafaabd3..d5b8458147b341a5232b34f6b525c89141f5d28c 100644 (file)
@@ -1000,9 +1000,9 @@ static Numeric replyTable[] = {
 /* 483 */
   { ERR_CANTKILLSERVER, ":You cant kill a server!", "483" },
 /* 484 */
-  { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop a network service", "484" },
+  { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop an IRC operator", "484" },
 /* 485 */
-  { 0 },
+  { ERR_ISREALSERVICE, "%s %s :Cannot kill, kick or deop a network service", "485" },
 /* 486 */
   { ERR_ACCOUNTONLY, "%s :You must be authed in order to message this user", "486" },
 /* 487 */
index d970133d30bf7716fc0f71ac5e2a418213fd8df1..eae4b4952e7618233d43658640331d4613ecdc91 100644 (file)
@@ -715,7 +715,10 @@ static const struct UserMode {
   { FLAG_DEBUG,       'g' },
   { FLAG_ACCOUNT,     'r' },
   { FLAG_HIDDENHOST,  'x' },
-  { FLAG_ACCOUNTONLY, 'R' }
+  { FLAG_ACCOUNTONLY, 'R' },
+  { FLAG_XTRAOP,      'X' },
+  { FLAG_NOCHAN,      'n' },
+  { FLAG_NOIDLE,      'I' }
 };
 
 /** Length of #userModeList. */
@@ -817,7 +820,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
     if (MyUser(sptr)) {
       const char* channel_name;
       struct Membership *member;
-      if ((channel_name = find_no_nickchange_channel(sptr))) {
+      if ((channel_name = find_no_nickchange_channel(sptr)) && !IsXtraOp(sptr)) {
         return send_reply(cptr, ERR_BANNICKCHANGE, channel_name);
       }
       /*
@@ -1352,6 +1355,24 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
         else
           ClearChannelService(sptr);
         break;
+      case 'X':
+        if (what == MODE_ADD)
+          SetXtraOp(sptr);
+        else
+          ClearXtraOp(sptr);
+        break;
+      case 'n':
+        if (what == MODE_ADD)
+          SetNoChan(sptr);
+        else
+          ClearNoChan(sptr);
+        break;
+      case 'I':
+        if (what == MODE_ADD)
+          SetNoIdle(sptr);
+        else
+          ClearNoIdle(sptr);
+        break;
       case 'g':
         if (what == MODE_ADD)
           SetDebug(sptr);
@@ -1388,8 +1409,15 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
      * new umode; servers can set it, local users cannot;
      * prevents users from /kick'ing or /mode -o'ing
      */
-    if (!FlagHas(&setflags, FLAG_CHSERV))
+    if (!FlagHas(&setflags, FLAG_CHSERV) && !IsOper(sptr))
       ClearChannelService(sptr);
+    if (!FlagHas(&setflags, FLAG_XTRAOP) && !IsOper(sptr))
+      ClearXtraOp(sptr);
+    if (!FlagHas(&setflags, FLAG_NOCHAN) && !(IsOper(sptr) || feature_bool(FEAT_USER_HIDECHANS)))
+      ClearNoChan(sptr);
+    if (!FlagHas(&setflags, FLAG_NOIDLE) && !IsOper(sptr))
+      ClearNoIdle(sptr);
+
     /*
      * only send wallops to opers
      */
index dc67e155619654668710d27feb1658812779436f..4e33e2fb2f00153182522eba26101b9b0813904f 100644 (file)
@@ -88,7 +88,7 @@ void do_who(struct Client* sptr, struct Client* acptr, struct Channel* repchan,
   if (repchan)
     chan = find_channel_member(acptr, repchan);
   else if ((!fields || (fields & (WHO_FIELD_CHA | WHO_FIELD_FLA)))
-           && !IsChannelService(acptr))
+           && !IsChannelService(acptr) && !IsNoChan(acptr)) 
   {
     for (chan = cli_user(acptr)->channel; chan; chan = chan->next_channel)
       if (PubChannel(chan->channel) &&