Author: Isomer <isomer@coders.net>
[ircu2.10.12-pk.git] / ircd / s_user.c
index ea7b01fa3596d9ca273b651a5600b4d653add9c2..c607f1b88258bbb9dd65e99645f1842c53a73783 100644 (file)
@@ -32,6 +32,7 @@
 #include "ircd.h"
 #include "ircd_alloc.h"
 #include "ircd_chattr.h"
+#include "ircd_features.h"
 #include "ircd_log.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
@@ -129,50 +130,6 @@ void user_count_memory(size_t* count_out, size_t* bytes_out)
   *bytes_out = userCount * sizeof(struct User);
 }
 
-/*
- * user_set_away - set user away state
- * returns 1 if client is away or changed away message, 0 if 
- * client is removing away status.
- * NOTE: this function may modify user and message, so they
- * must be mutable.
- */
-int user_set_away(struct User* user, char* message)
-{
-  char* away;
-  assert(0 != user);
-
-  away = user->away;
-
-  if (EmptyString(message)) {
-    /*
-     * Marking as not away
-     */
-    if (away) {
-      MyFree(away);
-      user->away = 0;
-    }
-  }
-  else {
-    /*
-     * Marking as away
-     */
-    unsigned int len = strlen(message);
-
-    if (len > TOPICLEN) {
-      message[TOPICLEN] = '\0';
-      len = TOPICLEN;
-    }
-    if (away)
-      away = (char*) MyRealloc(away, len + 1);
-    else
-      away = (char*) MyMalloc(len + 1);
-    assert(0 != away);
-
-    user->away = away;
-    strcpy(away, message);
-  }
-  return (user->away != 0);
-}
 
 /*
  * next_client
@@ -696,6 +653,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
         }
       }
     }
+    client_set_privs(new_client); /* set privs on user */
     /*
      * Set new nick name.
      */
@@ -1000,12 +958,13 @@ int whisper(struct Client* source, const char* nick, const char* channel,
 /*
  * added Sat Jul 25 07:30:42 EST 1992
  */
-void send_umode_out(struct Client *cptr, struct Client *sptr, int old)
+void send_umode_out(struct Client *cptr, struct Client *sptr, int old,
+                   int prop)
 {
   int i;
   struct Client *acptr;
 
-  send_umode(NULL, sptr, old, SEND_UMODES);
+  send_umode(NULL, sptr, old, SEND_UMODES & ~(prop ? 0 : FLAGS_OPER));
 
   for (i = HighestFd; i >= 0; i--) {
     if ((acptr = LocalClientArray[i]) && IsServer(acptr) &&
@@ -1069,6 +1028,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
   unsigned int tmpmask = 0;
   int snomask_given = 0;
   char buf[BUFSIZE];
+  int prop = 0;
 
   what = MODE_ADD;
 
@@ -1217,13 +1177,12 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
      */
     if (!(setflags & FLAGS_CHSERV))
       ClearChannelService(sptr);
-#ifdef WALLOPS_OPER_ONLY
     /*
      * only send wallops to opers
      */
-    if (!IsAnOper(sptr) && !(setflags & FLAGS_WALLOP))
+    if (feature_bool(FEAT_WALLOPS_OPER_ONLY) && !IsAnOper(sptr) &&
+       !(setflags & FLAGS_WALLOP))
       ClearWallops(sptr);
-#endif
   }
   if (MyConnect(sptr)) {
     if ((setflags & (FLAGS_OPER | FLAGS_LOCOP)) && !IsAnOper(sptr))
@@ -1238,15 +1197,21 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
    * Compare new flags with old flags and send string which
    * will cause servers to update correctly.
    */
-  if ((setflags & FLAGS_OPER) && !IsOper(sptr))
-    --UserStats.opers;
-  if (!(setflags & FLAGS_OPER) && IsOper(sptr))
+  if (!(setflags & FLAGS_OPER) && IsOper(sptr)) { /* user now oper */
     ++UserStats.opers;
+    client_set_privs(sptr); /* may set propagate privilege */
+  }
+  if (HasPriv(sptr, PRIV_PROPAGATE)) /* remember propagate privilege setting */
+    prop = 1;
+  if ((setflags & FLAGS_OPER) && !IsOper(sptr)) { /* user no longer oper */
+    --UserStats.opers;
+    client_set_privs(sptr); /* will clear propagate privilege */
+  }
   if ((setflags & FLAGS_INVISIBLE) && !IsInvisible(sptr))
     --UserStats.inv_clients;
   if (!(setflags & FLAGS_INVISIBLE) && IsInvisible(sptr))
     ++UserStats.inv_clients;
-  send_umode_out(cptr, sptr, setflags);
+  send_umode_out(cptr, sptr, setflags, prop);
 
   return 0;
 }
@@ -1261,7 +1226,11 @@ char *umode_str(struct Client *cptr)
   int   i;
   int   c_flags;
 
-  c_flags = cli_flags(cptr) & SEND_UMODES;        /* cleaning up the original code */
+  c_flags = cli_flags(cptr) & SEND_UMODES; /* cleaning up the original code */
+  if (HasPriv(cptr, PRIV_PROPAGATE))
+    c_flags |= FLAGS_OPER;
+  else
+    c_flags &= ~FLAGS_OPER;
 
   for (i = 0; i < USERMODELIST_SIZE; ++i) {
     if ( (c_flags & userModeList[i].flag))
@@ -1519,7 +1488,8 @@ int add_silence(struct Client* sptr, const char* mask)
     if (MyUser(sptr))
     {
       len += strlen(lp->value.cp);
-      if ((len > MAXSILELENGTH) || (++cnt >= MAXSILES))
+      if ((len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXSILES))) ||
+         (++cnt >= feature_int(FEAT_MAXSILES)))
       {
         send_reply(sptr, ERR_SILELISTFULL, mask);
         return -1;