- The big forward port. I probably broke lots of stuff, so please look over any
[ircu2.10.12-pk.git] / ircd / m_settime.c
index ad6ac3c13757fadf4f11b295d93e88c751b24b1a..6240b52c1f8c151cbe4672cd70fa99245be78602 100644 (file)
  *
  * parv[0] = sender prefix
  * parv[1] = new time
- * parv[2] = servername (Only used when sptr is an Oper).
+ * parv[2] = server name (Only used when sptr is an Oper).
  */
 int ms_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   time_t t;
-  long int dt;
+  long dt;
   static char tbuf[11];
   struct DLink *lp;
 
-  if (!IsPrivileged(sptr))
-    return 0;
-
   if (parc < 2)
     return need_more_params(sptr, "SETTIME");
 
-  if (parc == 2 && MyUser(sptr))
-    parv[parc++] = cli_name(&me);
-
   t = atoi(parv[1]);
   dt = TStime() - t;
 
   if (t < OLDEST_TS || dt < -9000000)
   {
-    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value", sptr);
+    if (IsServer(sptr))
+      protocol_violation(sptr, "SETTIME: Bad value (%Tu, delta %l)", t, dt);
+    else
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value (%Tu, "
+                    "delta %l)", sptr, t, dt);
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :SETTIME: Bad value", sptr);
     return 0;
   }
 
-  if (IsServer(sptr))           /* send to unlagged servers */
+  /* reset time... */
+  if (feature_bool(FEAT_RELIABLE_CLOCK))
   {
-    if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-      ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-      parv[1] = tbuf;
-    }
+    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
+    parv[1] = tbuf;
+  }
 
+  if (BadPtr(parv[2]))
+  {
     for (lp = cli_serv(&me)->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && MsgQLength(&(cli_sendQ(lp->value.cptr))) < 8000)
-       sendcmdto_one(sptr, CMD_NOTICE, lp->value.cptr, "%s", parv[1]);
+      if (cptr != lp->value.cptr)
+        sendcmdto_prio_one(sptr, CMD_SETTIME, lp->value.cptr, "%s", parv[1]);
   }
   else
   {
-    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-    parv[1] = tbuf;
     if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
-                            parv) != HUNTED_ISME)
+                             parv) != HUNTED_ISME)
+    {
+      /* If the destination was *not* me, but I'm RELIABLE_CLOCK and the
+       * delta is more than 30 seconds off, bounce back a corrected
+       * SETTIME
+       */
+      if (feature_bool(FEAT_RELIABLE_CLOCK) && (dt > 30 || dt < -30))
+        sendcmdto_prio_one(&me, CMD_SETTIME, cptr, "%s %C", parv[1], cptr);
       return 0;
+    }
   }
 
-  if (feature_bool(FEAT_RELIABLE_CLOCK)) {
+  if (feature_bool(FEAT_RELIABLE_CLOCK))
+  {
+    /* don't apply settime--reliable */
     if ((dt > 600) || (dt < -600))
-      sendcmdto_serv_butone(&me, CMD_WALLOPS, 0, ":Bad SETTIME from %s: %Tu",
-                           cli_name(sptr), t);
-    if (IsUser(sptr)) {
+      sendcmdto_serv_butone(&me, CMD_DESYNCH, 0, ":Bad SETTIME from %s: %Tu "
+                            "(delta %l)", cli_name(sptr), t, dt);
+    /* Let user know we're ignoring him */
+    if (IsUser(sptr))
+    {
       sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld "
                    "seconds %s : RELIABLE_CLOCK is defined", sptr,
                    (dt < 0) ? -dt : dt, (dt < 0) ? "forwards" : "backwards");
     }
-  } else {
+  }
+  else
+  {
     sendto_opmask_butone(0, SNO_OLDSNO, "SETTIME from %s, clock is set %ld "
                         "seconds %s", cli_name(sptr), (dt < 0) ? -dt : dt,
                         (dt < 0) ? "forwards" : "backwards");
+    /* Apply time change... */
     TSoffset -= dt;
-    if (IsUser(sptr)) {
+    /* Let the issuing user know what we did... */
+    if (IsUser(sptr))
+    {
       sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is set %ld seconds %s",
-                   sptr, (dt < 0) ? -dt : dt,
-                   (dt < 0) ? "forwards" : "backwards");
+                    sptr, (dt < 0) ? -dt : dt,
+                    (dt < 0) ? "forwards" : "backwards");
     }
   }
 
@@ -185,12 +201,12 @@ int ms_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 int mo_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   time_t t;
-  long int dt;
+  long dt;
   static char tbuf[11];
-  struct DLink *lp;
 
-  if (!IsPrivileged(sptr))
-    return 0;
+  /* Must be a global oper */
+  if (!IsOper(sptr))
+    return send_reply(sptr, ERR_NOPRIVILEGES);
 
   if (parc < 2)
     return need_more_params(sptr, "SETTIME");
@@ -199,6 +215,14 @@ int mo_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     parv[parc++] = cli_name(&me);
 
   t = atoi(parv[1]);
+  /* If we're reliable_clock or if the oper specified a 0 time, use current */
+  if (!t || feature_bool(FEAT_RELIABLE_CLOCK))
+  {
+    t = TStime();
+    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
+    parv[1] = tbuf;
+  }
+
   dt = TStime() - t;
 
   if (t < OLDEST_TS || dt < -9000000)
@@ -207,45 +231,30 @@ int mo_settime(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     return 0;
   }
 
-  if (IsServer(sptr))           /* send to unlagged servers */
-  {
-    if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-      ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-      parv[1] = tbuf;
-    }
+  if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
+                           parv) != HUNTED_ISME)
+    return 0;
 
-    for (lp = cli_serv(&me)->down; lp; lp = lp->next)
-      if (cptr != lp->value.cptr && MsgQLength(&(cli_sendQ(lp->value.cptr))) < 8000)
-       sendcmdto_prio_one(sptr, CMD_SETTIME, lp->value.cptr, "%s", parv[1]);
+  if (feature_bool(FEAT_RELIABLE_CLOCK))
+  {
+    if ((dt > 600) || (dt < -600))
+      sendcmdto_serv_butone(&me, CMD_DESYNCH, 0, ":Bad SETTIME from %s: %Tu "
+                            "(delta %l)", cli_name(sptr), t, dt);
+    if (IsUser(sptr))
+      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld seconds "
+                    "%s: RELIABLE_CLOCK is defined", sptr, (dt < 0) ? -dt : dt,
+                    (dt < 0) ? "forward" : "backward");
   }
   else
   {
-    ircd_snprintf(0, tbuf, sizeof(tbuf), "%Tu", TStime());
-    parv[1] = tbuf;
-    if (hunt_server_prio_cmd(sptr, CMD_SETTIME, cptr, 1, "%s %C", 2, parc,
-                            parv) != HUNTED_ISME)
-      return 0;
-  }
-
-  if (feature_bool(FEAT_RELIABLE_CLOCK)) {
-    if ((dt > 600) || (dt < -600))
-      sendcmdto_serv_butone(&me, CMD_WALLOPS, 0, ":Bad SETTIME from %s: %Tu",
-                           cli_name(sptr), t);
-    if (IsUser(sptr)) {
-      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is not set %ld "
-                   "seconds %s : RELIABLE_CLOCK is defined", sptr,
-                   (dt < 0) ? -dt : dt, (dt < 0) ? "forwards" : "backwards");
-    }
-  } else {
     sendto_opmask_butone(0, SNO_OLDSNO, "SETTIME from %s, clock is set %ld "
                         "seconds %s", cli_name(sptr), (dt < 0) ? -dt : dt,
                         (dt < 0) ? "forwards" : "backwards");
     TSoffset -= dt;
-    if (IsUser(sptr)) {
+    if (IsUser(sptr))
       sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :clock is set %ld seconds %s",
                    sptr, (dt < 0) ? -dt : dt,
                    (dt < 0) ? "forwards" : "backwards");
-    }
   }
 
   return 0;