implemented custom KeepConn Time Mode (+K <time>) and relay command for external...
[ircu2.10.12-pk.git] / ircd / s_user.c
index f42cf9a0130438611eb59540029820c7ee176904..60144878d25c049b891de1092960fc78262bca20 100644 (file)
@@ -589,6 +589,7 @@ static const struct UserMode {
   { FLAG_WEBIRC,      'W' },
   { FLAG_SEE_IDLETIME,'t' },
   { FLAG_SECURITY_SERV,'D' },
+  { FLAG_KEEPCONN_ENABLED, 'K' },
   { FLAG_HIDDENHOST,  'x' },
   { FLAG_NOTCONN,     'Z' }
 };
@@ -728,7 +729,23 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
   }
   else {
     /* Local client setting NICK the first time */
-    strcpy(cli_name(sptr), nick);
+    if(!force)
+      strcpy(cli_name(sptr), nick);
+    else {
+      /* use a "temponary" nick here (we'll switch later) */
+      char tmpnick[NICKLEN + 2];
+      int tmpnickend; 
+      strcpy(tmpnick, nick);
+      /* we need at least 10 characters */
+      if (strlen(tmpnick) > IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN)) - 10)
+        tmpnick[IRCD_MIN(NICKLEN, feature_int(FEAT_NICKLEN))-10] = '\0';
+      tmpnickend = strlen(tmpnick);
+      
+      do { /* get a non-used nick... */
+        sprintf(tmpnick + tmpnickend, "[rz%d]", ircrandom() % 10000);
+      } while(FindClient(tmpnick));
+      strcpy(cli_name(sptr), tmpnick);
+    }
     hAddClient(sptr);
     return auth_set_nick(cli_auth(sptr), nick);
   }
@@ -1070,6 +1087,25 @@ hide_hostmask(struct Client *cptr, unsigned int flag)
     else {
         SetDelayedJoin(chan);
     }
+    
+    /*
+    * Check if the client is actually overriding a ban with the
+    * mask change, if so, kick him out of the channel.
+    * We have to proceed that way to ensure data consistency (join + kick)
+    */
+    if (find_ban(cptr, chan->channel->banlist)) {
+      /* Silentely kick in case of delayed join */
+      if (chan->channel->mode.mode & MODE_DELJOINS) {
+        sendcmdto_one(&his, CMD_KICK, cptr, "%H %C :Ban override", chan->channel, cptr);
+        CheckDelayedJoins(chan->channel);
+        
+      } else {
+        /* Otherwise publicly kick */
+        sendcmdto_serv_butone(&me, CMD_KICK, NULL, "%H %C :Ban override", chan->channel, cptr);
+        sendcmdto_channel_butserv_butone(&his, CMD_KICK, chan->channel, NULL, 0, "%H %C :Ban override", chan->channel, cptr);
+        make_zombie(chan, cptr, &me, &me, chan->channel);
+      }
+    }
   }
   return 0;
 }
@@ -1100,7 +1136,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
   char buf[BUFSIZE];
   int prop = 0;
   int do_host_hiding = 0;
-  char* account = NULL, *fakehost = NULL;
+  char* account = NULL, *fakehost = NULL, *keepconn = NULL;
   struct Membership *chan;
 
   what = MODE_ADD;
@@ -1272,6 +1308,16 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
         else
           ClearWebIRC(sptr);
         break;
+      case 'K':
+        if (what == MODE_ADD) {
+          if(*(p + 1) == 0)
+            break;
+          keepconn = *(++p);
+          SetKeepConnEnabled(sptr);
+        } else {
+          ClearKeepConnEnabled(sptr);
+        }
+        break;
       case 'r':
         if (*(p + 1) && (what == MODE_ADD)) {
           account = *(++p);
@@ -1348,6 +1394,8 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
       ClearHiddenOper(sptr);
     if (!FlagHas(&setflags, FLAG_OVERRIDECC) && IsOverrideCC(sptr) && !HasPriv(sptr, PRIV_UMODE_OVERRIDECC))
       ClearOverrideCC(sptr);
+    if (!FlagHas(&setflags, FLAG_KEEPCONN_ENABLED) && IsKeepConnEnabled(sptr) && !HasPriv(sptr, PRIV_SET_KEEPCONN))
+      ClearKeepConnEnabled(sptr);
     /* Opers are able to fake the webirc usermode only if FEAT_FAKE_WEBIRC is true. */
     if (!FlagHas(&setflags, FLAG_WEBIRC) && IsWebIRC(sptr) && !(feature_bool(FEAT_FAKE_WEBIRC) && IsOper(sptr)))
       ClearWebIRC(sptr);
@@ -1408,6 +1456,9 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
   if (!FlagHas(&setflags, FLAG_FAKEHOST) && IsFakeHost(sptr)) {
     ircd_strncpy(cli_user(sptr)->fakehost, fakehost, HOSTLEN);
   }
+  if (!FlagHas(&setflags, FLAG_KEEPCONN_ENABLED) && IsKeepConnEnabled(sptr)) {
+    sptr->keepconn = atoi(keepconn);
+  }
 
   if (IsRegistered(sptr)) {
     if(do_host_hiding)