implemented custom KeepConn Time Mode (+K <time>) and relay command for external...
authorpk910 <philipp@zoelle1.de>
Wed, 26 Dec 2012 07:19:51 +0000 (08:19 +0100)
committerpk910 <philipp@zoelle1.de>
Wed, 26 Dec 2012 07:39:59 +0000 (08:39 +0100)
include/client.h
ircd/ircd.c
ircd/m_quit.c
ircd/m_relay.c
ircd/s_bsd.c
ircd/s_user.c

index a86633d2652d3c0aece42f9a0dfb0dff575747f1..36060fe0da83c88fdc4c34c802cba6726dcc71c8 100644 (file)
@@ -138,6 +138,7 @@ enum Priv
     PRIV_UNLIMITED_TARGET, /**< unlimited target changes */
     PRIV_UMODE_OVERRIDECC, /**< can set umode +c (override cmodes +cC) */
     PRIV_NOAMSG_OVERRIDE, /**< can override the +M channelmode */
+    PRIV_SET_KEEPCONN, /**< can set KeepConn time by its own */
     PRIV_LAST_PRIV /**< number of privileges */
   };
 
@@ -192,6 +193,7 @@ enum Flag
     FLAG_WEBIRC,                    /**< Is a WebIRC client with spoofed host/ip */
     FLAG_SEE_IDLETIME,              /**< Can see idletime of +I users. */
        FLAG_SECURITY_SERV,             /**< Securityflag, that can only be set by IAuth */
+    FLAG_KEEPCONN_ENABLED,          /**< special KeepConn time is set */
     FLAG_LAST_FLAG,                 /**< number of flags */
     FLAG_LOCAL_UMODES = FLAG_LOCOP, /**< First local mode flag */
     FLAG_GLOBAL_UMODES = FLAG_OPER  /**< First global mode flag */
@@ -277,7 +279,8 @@ struct Client {
   char cli_webirc[NICKLEN + 1];   /**< Contains the name of the WebIRC block */
   char           cli_yxx[4];      /**< Numeric Nick: YY if this is a
                                      server, XXX if this is a user */
-  unsigned int maxchans;
+  unsigned int maxchans : 8;
+  unsigned int keepconn : 24;
   char cli_connclass[NICKLEN + 1];
   time_t         cli_firsttime;   /**< time client was created */
   time_t         cli_lastnick;    /**< TimeStamp on nick */
@@ -649,10 +652,12 @@ struct Client {
 #define IsWebIRC(x)             HasFlag(x, FLAG_WEBIRC)
 /** Return non-zero if the client can see idletime of +I users. */
 #define IsSeeIdletime(x)        HasFlag(x, FLAG_SEE_IDLETIME)
-#define IsSecurityServ(x)        HasFlag(x, FLAG_SECURITY_SERV)
+#define IsSecurityServ(x)       HasFlag(x, FLAG_SECURITY_SERV)
+/** Return non-zero if the client has a special KeepConn Time set. */
+#define IsKeepConnEnabled(x)    HasFlag(x, FLAG_KEEPCONN_ENABLED)
 /** Return non-zero if the client has a fakehost. */
 #define IsFakeHost(x)           HasFlag(x, FLAG_FAKEHOST)
-#define IsFakeIdent(x)           HasFlag(x, FLAG_FAKEIDENT)
+#define IsFakeIdent(x)          HasFlag(x, FLAG_FAKEIDENT)
 
 /** Return non-zero if the client has operator or server privileges. */
 #define IsPrivileged(x)         (IsAnOper(x) || IsServer(x))
@@ -725,6 +730,8 @@ struct Client {
 /** Mark a client as being able to see idletime of +I users. */
 #define SetSeeIdletime(x)       SetFlag(x, FLAG_SEE_IDLETIME)
 #define SetSecurityServ(x)      SetFlag(x, FLAG_SECURITY_SERV)
+/** Mark a client as having a special KeepConn Time set. */
+#define SetKeepConnEnabled(x)   SetFlag(x, FLAG_KEEPCONN_ENABLED)
 
 /** Return non-zero if \a sptr sees \a acptr as an operator. */
 #define SeeOper(sptr,acptr) ((IsAnOper(acptr) && \
@@ -785,6 +792,8 @@ struct Client {
 /** Make client no longer being able to see idletime of +I users. */
 #define ClearSeeIdletime(x)     ClrFlag(x, FLAG_SEE_IDLETIME)
 #define ClearSecurityServ(x)    ClrFlag(x, FLAG_SECURITY_SERV)
+/** Remove the client's mark of having a special KeepConn Time set. */
+#define ClearKeepConnEnabled(x) ClrFlag(x, FLAG_KEEPCONN_ENABLED)
 
 /* free flags */
 #define FREEFLAG_SOCKET        0x0001  /**< socket needs to be freed */
index ad6ae5fb5f9699e4f7e521575496efa005eb9e8a..2b6427de22592c7848e0ab6fc7fa3e1b5a322cb2 100644 (file)
@@ -343,11 +343,10 @@ static void check_pings(struct Event* ev) {
     /* We don't need to check zombies here */
     if (IsNotConn(cptr)) {
       assert(IsUser(cptr));
-      /* for now: reap after fixed time (5 minutes) */
-      if ((CurrentTime - cli_user(cptr)->last) >= 300) {
+      if ((CurrentTime - cli_user(cptr)->last) >= (IsKeepConnEnabled(cptr) ? cptr->keepconn : 300)) {
         SetFlag(cptr, FLAG_DEADSOCKET);
         /* this will be used as exit message */
-        ircd_strncpy(cli_info(cptr), "Ping timeout", REALLEN);
+        ircd_strncpy(cli_info(cptr), "Zombie timeout", REALLEN);
       } else
         continue;
     }
index 9c06b31ccc78d29684a9622f9c2f20ebbff76eba..0aff8f0e83762c18c1e2648c1aaf783e5ca3811f 100644 (file)
@@ -105,7 +105,7 @@ int m_quit(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   assert(0 != sptr);
   assert(cptr == sptr);
 
-  if (!ircd_strcmp(parv[parc - 1], "ZOMBIE")) {
+  if (IsKeepConnEnabled(sptr) || !ircd_strcmp(parv[parc - 1], "ZOMBIE")) {
     zombie_client(&me, &me, sptr);
     return 0;
   }
index 3f0dcf6699cd8a37ac5c6ddf89b6e8f64c439ad1..b31f7d7cdae1fc46a9b9d9440aa829ad896a7b2c 100644 (file)
@@ -240,8 +240,17 @@ signed int ms_relay(struct Client* cptr, struct Client* sptr, signed int parc, c
                 mode_a_check_altchan(acptr,chptr->mode.altchan);
             send_reply(acptr, ERR_JOINACCESS, parv[3], feature_str(FEAT_ERR_JOINACCESS));
         }
+    } else if(strcmp("KC", parv[2]) == 0 && parc > 2) {
+        struct Client *acptr;
+        if(acptr = findNUser(parv[1])) {
+            char *args[4];
+            args[0] = NULL;
+            args[1] = NULL;
+            args[2] = "+K";
+            args[3] = parv[3];
+            set_user_mode(sptr, acptr, 4, args, ALLOWMODES_ANY);
+        }
     }
-
     return 0;
 }
 
index fb842764a4152c36de12749765db47110bcb908e..542a41224a4c0f3143bc7b7082a4d58419d4a81c 100644 (file)
@@ -967,7 +967,9 @@ void client_sock_callback(struct Event* ev)
 
   assert(0 == cptr || 0 == cli_connect(cptr) || con == cli_connect(cptr));
 
-  if (fallback) {
+  if (fallback && IsKeepConnEnabled(cptr)) {
+    zombie_client(&me, &me, cptr);
+  } else if (fallback) {
     const char* msg = (cli_error(cptr)) ? strerror(cli_error(cptr)) : fallback;
     if (!msg)
       msg = "Unknown error";
index 96d88a15e3db5ab173052a8a5c78159063c90e8f..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' }
 };
@@ -1135,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;
@@ -1307,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);
@@ -1383,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);
@@ -1443,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)